CIDRKit

Subnet Calculator

Enter a CIDR block, a dotted mask, a wildcard mask or an address range and get every derived value. Collapses 50,000 CIDRs in 188 ms. Nothing you paste is uploaded.

Also accepts 10.0.0.0 255.0.0.0 · 10.0.0.0 0.255.255.255 · 192.168.0.0 - 192.168.1.255

Need this exact input on another machine? Copy link carries it in the part of the address the browser never sends anywhere.

Give it anything you actually have on hand: 10.0.0.0/8, 10.0.0.0 255.0.0.0, the Cisco form 10.0.0.0 0.255.255.255, a range like 192.168.0.0 - 192.168.1.255, or a bare address, which is read as a single host. It answers with the network address, netmask, wildcard mask, broadcast, usable range, and both counts.

The second tab does the job that has no good free tool: take a pasted list of CIDR blocks — a firewall allow-list, a route export — and collapse it into the smallest equivalent set. That is not the same as sorting it. Two blocks merge only when they are the same size, adjacent, and aligned on the parent boundary, and the alignment condition is where hand-rolled implementations get it wrong.

Your input never leaves the tab — the share link keeps it in the address fragment, which browsers do not transmit, and there is no account and no rate limit. Open the Network panel while you work: besides the ad tag this build loads, the only entries are the page's own four files, and none of them carries what you typed.

CIDR to IP range

Paste a block such as 198.51.100.0/24 into the field above and the range is already in the answer: First usable host 198.51.100.1, Last usable host 198.51.100.254, Total addresses 256, Usable hosts 254. The two addresses missing between 198.51.100.0 and 198.51.100.255 are the network address and the broadcast address, which is why a firewall object or an ACL usually wants the whole block and a DHCP pool wants the usable pair. The reverse direction works as well: the input accepts 192.168.0.0 - 192.168.1.255 and answers 192.168.0.0/23, on the condition that the range is exactly one aligned block — a ragged range such as 192.168.0.1 - 192.168.1.200 is refused there on purpose — the calculator answers one network, and a ragged range is not one network. The error names the smallest block that would cover it, and the Range to CIDR set tab splits the same input into the aligned blocks that cover it exactly. The error names the smallest block that would cover it — 192.168.0.0/23, which adds 56 addresses you did not ask for — and returns nothing, because silently widening a range is how an ACL ends up open to a whole /23.

Small prefixes follow the interface rules rather than the minus-two rule, and that is measured rather than asserted: 192.168.1.1/31 reports 2 usable hosts (RFC 3021 point-to-point) and 192.168.1.1/32 reports 1. For IPv6 the same rows stay exact — 2001:db8::/32 reports 79,228,162,514,264,337,593,543,950,336 addresses — and the broadcast row is left blank because IPv6 has no broadcast address.

IP range to CIDR

Paste 10.0.0.5 - 10.0.0.200 into the Range to CIDR set tab and you get back 10.0.0.5/32, 10.0.0.6/31, 10.0.0.8/29, 10.0.0.16/28, 10.0.0.32/27, 10.0.0.64/26, 10.0.0.128/26, 10.0.0.192/29, 10.0.0.200/32 — nine blocks, 196 addresses, exactly the range you asked for and not one address more. That is the answer a firewall or a route object needs when a range was handed to you by someone who did not think about alignment.

Why the block count has a ceiling: at each step the algorithm takes the largest block that is aligned at the current address and still fits under the end, so one block per bit can be spent climbing out of a ragged start and one again climbing down to a ragged end. 64 blocks max for IPv4, 256 for IPv6, whatever the size of the range — the list cannot blow up on you.

The set is minimal in the strict sense: no two of its blocks can be merged into a valid larger block. That property is not asserted here, it is checked — every one of the generated answer sets was fed through ipaddress.collapse_addresses and came back unchanged, and adjacency plus the address total are re-checked per case in the test page this build ships.

Measured, not promised

WhatSizeTimeResult
One subnet calculation200 CIDRs0.042 ms eachfast enough to recompute on every keystroke, which is what it does
Collapse a list1,000 CIDRs6.8 ms1,000 blocks out
Collapse a list10,000 CIDRs35.5 ms9,993 blocks out
Collapse a list50,000 CIDRs187.7 ms49,855 blocks out
Collapse a worst case10,000 /25s that chain-merge20.2 ms5 blocks out
Enumerate subnets/8 split by +24, first 1,048,576 formatted649.6 ms16,777,216 counted

Measured in Chrome 152 on Windows 11. The first row is why the result updates as you type instead of waiting for a button. The 50,000-row collapse is the one that matters in practice — a firewall export nobody wants to tidy by hand — and it took 187.7 ms. Collapsing is not a two-at-a-time containment scan: that version was written first, and it hung the tab at fifty thousand inputs.

Correctness: checked against a reference implementation

The interesting claim about a calculator is not speed. It is whether the answer is right — and for CIDR maths there is an honest way to demonstrate that: compare against something authoritative.

Every result this page produces is checked against Python's standard-library ipaddress module, the same code that ships inside CPython and the reference most network tooling is regression-tested against. The test vectors are generated from it, not hand-written by someone who thought they knew the answers.

Fifty-six assertion groups in total, in a page that ships with the site (/test/). There is no CI behind it: the harness is re-run by hand before each publish, which is the honest version of that sentence. Two real bugs were caught that way before this paragraph was written: an IPv6 formatter that emitted its groups in reverse order, and a mask validator that compared a BigInt against a Number with !==, which made every dotted netmask look invalid. Neither is visible by eye.

Where a competitor is confidently wrong, it is usually one of three things: applying n − 2 to a /31 or /32, reading a wildcard mask as a netmask, or merging two adjacent blocks that are not actually aligned. All three are covered by the vectors above.

What each line means

The calculator answers with a table. The other four panels answer with a line or two of text and a list. Everything below uses the page's own wording, so you can read a line on the screen and find it here.

Calculator.

LineWhat it is
CIDRThe block in slash notation: network address plus prefix length. It is the shortest exact name of the range, and it is the form a firewall rule or an ACL wants.
Network addressThe first address of the block — all host bits zero. This is the name of the network, not an assignable address.
NetmaskOnes for the network part, zeros for the host part. A /27 is 255.255.255.224.
Wildcard maskThe exact inverse of the netmask. Cisco ACLs and iptables take this form, which is why the input box accepts it in either direction.
Prefix lengthHow many leading bits are network bits. One step up halves the block, one step down doubles it — that is the entire arithmetic of a subnet table.
Broadcast addressThe last address of the block — all host bits one. Every host on the segment hears it, so it is never assignable.
First usable host / Last usable hostThe assignable range, for when you are handing out static addresses and need the boundaries rather than the arithmetic.
Total addresses232 − prefix for IPv4, 2128 − prefix for IPv6. Anything past seven digits is printed abbreviated with the exact value beside it, because a /8 is 16,777,216 and a /64 is not a number you can hold in your head.
Usable hostsTotal minus network and broadcast, with the exceptions explained under “Why usable hosts are total minus two”.
Range classPrivate means the set Python's ipaddress calls private — RFC 1918 plus loopback, link-local and the other special-purpose ranges, so 198.51.100.0/24 does light it up. Then loopback, link-local, multicast and reserved, which are the five cross-checked against CPython; CGNAT, documentation and benchmarking come from this site's own prefix tables. For IPv6 the line says why it is not reported at all.
NoteAppears only when your input had host bits set. It names the block your address actually falls in instead of quietly rewriting what you typed — you still get one answer, and you still see that the tool moved something.
version 4 · parsed from …The line under the table: which family the engine settled on, and your input exactly as it was read. When you supplied a netmask, a wildcard, or an address with host bits set, this is where you can see what it decided.

The other four panels.

What you seeWhat it means
… blocks in → … out · … ms · nothing uploadedCollapse: how many lines you pasted, how many the tool returned, how long it took. The list underneath is the smallest set of blocks that covers exactly what you pasted — nothing added, nothing dropped. nothing uploaded is not a slogan: the arithmetic runs in this tab, so the only number this page could have to say about your input is how long it took.
Cannot parse that / Cannot read that rangeOne line of your input is not valid. The message names the line and the panel stops — you never get a half-computed answer with one bad row silently missing from it.
Each subnet: /20 (4094 hosts)Split: the prefix every child block gets, and how many assignable addresses are inside one of them. If the number you asked for was not a power of two, the line says it was rounded up — equal-size CIDR children only exist at powers of two, so the tool will not invent a /20.5 to match your request.
Showing the first 2,000.The on-screen list is capped so a big split does not freeze the tab. Download all N lines gives you the full set. Past 200,000 lines the button is replaced by Too many to hand you as a file, because generating it would hang the browser instead of helping.
10.0.5.7 is inside 10.0.0.0/16Contains: the whole answer, in one line. Membership, not assignability — the network address and the broadcast address are inside the block even though nothing may be configured on them. The line reads is NOT inside when the address is outside.
BlocksRange: how many CIDR blocks your range came out as. When that number is 1 your range was already an aligned block, and the page says the range is already one aligned block instead of pretending it split something.
Addresses coveredHow many addresses from your first to your last, inclusive — that is the span you asked for, not a block size. It is the number the check below has to reproduce.
FamilyIPv4 or IPv6. A start and an end from different families are refused rather than coerced, because a range that mixes them has no correct answer.
CheckThe tool adds up the sizes of the blocks it is about to hand you and prints that sum next to the span, so you can see for yourself that the two agree: blocks sum to 196 — the same number.
The set, in orderNumbered because the order is part of the answer. The blocks are contiguous and each one begins where the previous one ends — which is also the fastest way to spot a gap by eye.

Why usable hosts are total minus two

Two addresses in every block are spoken for: the network address (how the block is named in routing) and the broadcast address (which every host on the segment hears). So a /24 is 256 addresses but 254 hosts, and a /27 is 32 but 30. It is not padding and not a convention you can skip — configure a DHCP pool that includes the network address and you have taken someone's host.

Two sizes break the rule, and a calculator that does not know them is a source of real outages:

This page reports 2 and 1 respectively because the test vectors include both and CPython agrees. For IPv6 it does not apply minus-two at all: there is no broadcast address, so only the subnet-router anycast address (the first) is reserved and the last address of the block is a usable host — and a /127 or /128 reserves nothing, which is CPython's rule. The vectors carry all three IPv6 cases separately — 2001:db8::/126 gives ::1 to ::3 and 3 hosts, /127 gives both ends and 2 hosts, /128 gives 1. Prefixes too large to materialise reuse the same rule, which the generator checks against list(net.hosts()) on 20 materialisable prefixes (/24-/32 and /118-/128) before applying it to the rest.

CIDR, netmask, wildcard — three spellings, one meaning

These all describe the same block:

10.0.0.0/8
10.0.0.0 255.0.0.0        # dotted netmask
10.0.0.0 0.255.255.255    # wildcard / hostmask, Cisco ACL form
10.0.0.0 - 10.255.255.255 # inclusive range

The input box accepts all four, and it will not silently reinterpret the third: 255.255.0.255 is neither a valid netmask (ones must form one run at the top) nor a valid wildcard (ones must form one run at the bottom), so it is rejected with that explanation rather than rounded to something plausible. A mask copied from the wrong column is worth an error message, not a guess.

One behaviour to know about: paste 192.168.1.37/24 and you get 192.168.1.0/24, because host bits are not part of a network identifier. The page says so and shows the address you came from, instead of pretending you typed something else.

CIDR chart: every prefix, computed

Hand-drawn CIDR charts go stale and are usually mistyped. This one is computed at build time by Python's ipaddress module - the same reference the calculator is tested against - and the build fails if the page and the arithmetic disagree. Every number below is exact.

IPv4, every prefix.

PrefixNetmaskWildcardTotal addressesUsable hosts
/00.0.0.0255.255.255.2554,294,967,2964,294,967,294
/1128.0.0.0127.255.255.2552,147,483,6482,147,483,646
/2192.0.0.063.255.255.2551,073,741,8241,073,741,822
/3224.0.0.031.255.255.255536,870,912536,870,910
/4240.0.0.015.255.255.255268,435,456268,435,454
/5248.0.0.07.255.255.255134,217,728134,217,726
/6252.0.0.03.255.255.25567,108,86467,108,862
/7254.0.0.01.255.255.25533,554,43233,554,430
/8255.0.0.00.255.255.25516,777,21616,777,214
/9255.128.0.00.127.255.2558,388,6088,388,606
/10255.192.0.00.63.255.2554,194,3044,194,302
/11255.224.0.00.31.255.2552,097,1522,097,150
/12255.240.0.00.15.255.2551,048,5761,048,574
/13255.248.0.00.7.255.255524,288524,286
/14255.252.0.00.3.255.255262,144262,142
/15255.254.0.00.1.255.255131,072131,070
/16255.255.0.00.0.255.25565,53665,534
/17255.255.128.00.0.127.25532,76832,766
/18255.255.192.00.0.63.25516,38416,382
/19255.255.224.00.0.31.2558,1928,190
/20255.255.240.00.0.15.2554,0964,094
/21255.255.248.00.0.7.2552,0482,046
/22255.255.252.00.0.3.2551,0241,022
/23255.255.254.00.0.1.255512510
/24255.255.255.00.0.0.255256254
/25255.255.255.1280.0.0.127128126
/26255.255.255.1920.0.0.636462
/27255.255.255.2240.0.0.313230
/28255.255.255.2400.0.0.151614
/29255.255.255.2480.0.0.786
/30255.255.255.2520.0.0.342
/31255.255.255.2540.0.0.122
/32255.255.255.2550.0.0.011

Reading the last column. Usable hosts is the total minus the network address and the broadcast address, except on the two rows at the bottom: a /31 keeps both addresses (RFC 3021, point-to-point links) and a /32 keeps its one address. The calculator applies the same rule, so a /31 on screen really does say 2.

The digits are spelled out here even though the calculator abbreviates anything past seven digits - a chart exists to be read, a result row exists to fit.

IPv6, the prefixes that turn up.

PrefixTotal addressesUsable addressesHow many /64s fit
/322^962^96 - 14,294,967,296
/482^802^80 - 165,536
/562^722^72 - 1256
/602^682^68 - 116
/642^642^64 - 11
/962^322^32 - 1—
/1122^162^16 - 1—
/1202^82^8 - 1—
/1242^42^4 - 1—
/1262^23—
/1272^12—
/1282^01—

IPv6. Sizes are written as powers of two, because the decimal form of a /64 is 18,446,744,073,709,551,616 - twenty digits that do not fit a line. That number is exactly the entire IPv4 address space squared. Only the first address of a v6 subnet is reserved (the subnet-router anycast address) and there is no broadcast address, so usable is total minus one, not minus two - except on /127 and /128, where nothing is reserved. A dash in the last column means the question does not apply: a prefix longer than /64 is a slice of one subnet, not a container of subnets.

Special-purpose IPv4 ranges.

RangeThe calculator flags it asWhy it is set aside
0.0.0.0/8privateRFC 1122 "this host on this network"; never a valid destination.
10.0.0.0/8privateRFC 1918 private use; sixteen million addresses in one block.
100.64.0.0/10CGNATRFC 6598 carrier-grade NAT. Not RFC 1918, so most private-address lists miss it.
127.0.0.0/8private · loopbackRFC 1122 loopback. The whole /8, not just 127.0.0.1.
169.254.0.0/16private · link-localRFC 3927 link-local: what a host gives itself when DHCP finds nothing.
172.16.0.0/12privateRFC 1918 private use; sixteen /16s, 172.16 through 172.31.
192.0.0.0/29privateIETF protocol assignments (RFC 6890). Python counts it private, so the flag says private.
192.0.2.0/24private · documentationRFC 5737 TEST-N-1: documentation and examples.
192.168.0.0/16privateRFC 1918 private use; the range most home gear ships in.
198.18.0.0/15private · benchmarkingRFC 2544 benchmarking: device test traffic, not real traffic.
198.51.100.0/24private · documentationRFC 5737 TEST-N-2: documentation and examples.
203.0.113.0/24private · documentationRFC 5737 TEST-N-3: documentation and examples.
224.0.0.0/4multicastRFC 5771 multicast.
240.0.0.0/4private · reservedReserved for future use; never assignable.
255.255.255.255/32private · reservedLimited broadcast, RFC 919. Flagged private and reserved at once - Python's list is wider than RFC 1918.

The ranges that are not yours. The middle column is the flag the calculator prints under its result, same words. Two of these rows are worth knowing by heart: 100.64.0.0/10 is carrier-grade NAT and is not in RFC 1918, so a private-address check that only knows the three classic ranges will let it through; and the three /24s in the 192.0.2, 198.51.100 and 203.0.113 ranges are RFC 5737 documentation space - correct for examples, wrong for a config you intend to run.

Alignment, because it is the most common mistake. A CIDR block starts on its own boundary: 192.168.1.0/24 is a block, 192.168.1.7/24 is not - the host bits are not zero. Paste the second one into the calculator and it will tell you which block it parsed from, rather than silently rewriting your input. For IPv6 documentation space the equivalent range is 2001:db8::/32 (RFC 3849).

Collapsing a list, and why alignment matters

Two blocks merge into their parent only when all three hold: same prefix length, numerically adjacent, and the left one starts on an even multiple of the parent's size. The third condition is the one people miss.

10.0.0.0/25 + 10.0.0.128/25  →  10.0.0.0/24   ✓ adjacent and aligned
10.0.0.128/25 + 10.0.1.0/25  →  no merge       ✗ adjacent, but not a parent pair

That second case is the trap. 10.0.0.128/25 and 10.0.1.0/25 sit right next to each other and together span 256 addresses, but they are not a /24, so a tool that prints 10.0.0.128/23 has produced an invalid network — one that ip address add, a router, or a cloud security group will reject. Try it in the collapse tab and you get two rows back.

Removing blocks already covered by a larger one is the other half: put 10.0.0.0/8 next to 10.1.2.0/24 and the /24 disappears, which is usually the point — fewer rules, same permission set.

Check the answer yourself

Do not take a web page's word for it, including this one. Python is in every developer environment and is what this page is tested against:

python3 -c "import ipaddress as i, sys
n = i.ip_network(sys.argv[1], strict=False)
print(n, n.network_address, n.netmask,
      n.hostmask, n.broadcast_address,
      n.num_addresses)" 10.0.0.37/24
# or the dedicated tools
ipcalc 192.168.1.0/26
sipcalc 192.168.1.0/26

For the collapse tab, cross-check with ipaddress.collapse_addresses — it is four lines and it agrees with this page on every generated vector.

What this page deliberately does not do

Frequently asked questions

Does my IP data get uploaded?

No. Parsing and arithmetic happen in the same tab; there is no request in the code path that parses your input.

Why does a /31 show 2 usable hosts instead of 0?

Because RFC 3021 reserves /31 for point-to-point links, where both addresses are usable — that is the entire reason the size exists. Applying the usual minus-two would report zero hosts for a working link, so this page follows the standard. A /32 gets one host for a comparable reason.

Can I enter a wildcard mask instead of a netmask?

Yes. 10.0.0.0 0.255.255.255 is accepted alongside the dotted-netmask and /8 forms. If what you give is neither a valid netmask nor a valid wildcard it is rejected with an explanation, not assumed to be one of them.

Why did my address change when I typed host bits?

It should have. 192.168.1.37/24 and 192.168.1.0/24 name the same network, and a network identifier never carries host bits. The page shows you both so nothing changed silently — echoing your typo back at you would hide the useful half of the answer.

Can it merge a list of CIDRs?

Yes — the collapse tab. Paste one block per line (or comma-separated) and it returns the minimal equivalent set, dropping anything already inside a larger block. Measured: 50,000 entries in 187.7 ms. It is checked against Python's collapse_addresses on 9 cases (20 capability checks in total, the rest being split and containment), including the alignment trap.

Does it handle IPv6?

For arithmetic, yes — including counts up to 2^128, which a plain JavaScript number cannot hold. For the private/reserved flags, no: the IPv6 registries are long enough that half-copying them would be worse than silence, so those fields are omitted rather than approximated.

Is 100.64.0.0/10 private?

It is the CGNAT range from RFC 6598 — shared among one carrier's customers, not globally routable, and not RFC 1918. CPython's is_private does not count it as private, so this page does not either; it reports a separate CGNAT flag instead, because "is this my carrier's NAT space" is the question people actually have.

Why is there no Class A/B/C column?

Classful addressing was superseded by CIDR in 1993. A /22 is "Class C" by first octet and a 1,024-address block in fact; the label answers no question the prefix does not answer better.