What this calculator does
This calculator parses and validates any IPv6 address or prefix, showing its compressed and expanded forms, network range, total address count, /64 subnet count, and reverse DNS (ip6.arpa) name. Beyond that single-address view, it also splits a prefix into smaller subnets with a bounded window and index-based navigation rather than ever listing a full split, classifies an address against both the IANA IPv6 Special-Purpose Address Registry and the general IANA IPv6 Address Space registry (including scope-aware multicast handling), shows a bit-level binary breakdown of the network prefix boundary, exports a bounded range of split subnets as CSV, compares any two prefixes for their exact relationship, and reduces a list of prefixes to the smallest equivalent set. See the methodology note at the bottom of this page for how each of these is tested.
128 bits, not 32
An IPv6 address is 128 bits, written as eight groups of four hex digits separated by colons — 2001:0db8:0000:0000:0000:0000:0000:0001 is the fully expanded form of an address most people would write as 2001:db8::1. That compressed form follows specific rules from RFC 5952: use lowercase hex, drop leading zeros within each group, and replace the single longest run of consecutive all-zero groups with :: (a run of exactly one zero group is left as 0 rather than compressed, and if two runs tie for longest, the leftmost one wins). This tool's compression was tested against those exact rules, plus 500 randomly generated addresses cross-checked against Python's own IPv6 library, before this page shipped.
IPv6 has no broadcast address
Unlike IPv4, IPv6 doesn't reserve a "broadcast" address at the top of a range — there's no equivalent concept. What this tool calls the "last address" of a prefix is simply the highest address in that numeric range, not a special destination. The closest IPv6 equivalent for one-to-many communication is multicast: ff02::1, for example, addresses all nodes on the local link.
Splitting a prefix — why this never lists every subnet
Splitting a /32 into /64 blocks already implies over 4 billion subnets; a /0 split into /64 implies more than 18 quintillion. No browser (and no person) can usefully page through that as a plain list, so this tool never tries to: it shows the first and last several subnets directly, then lets you jump straight to any specific subnet by its index and browse a small window around it. That index is handled as an arbitrary-precision integer throughout — typing an index in the billions works exactly the same way as typing 5, with no silent rounding once a number gets large.
What "Classification" actually tells you
An IPv6 address either falls inside one of IANA's IPv6 Special-Purpose Address Registry entries — loopback, documentation, unique local, link-local, and a couple dozen narrow protocol-specific ranges — or it doesn't, in which case this tool checks IANA's separate, more general IPv6 Address Space registry, which labels the entire rest of the address space at the top level — including 2000::/3 as "Global Unicast" and, e.g., 4000::/3 as "Reserved by IETF." A vague "Reserved / Unassigned" is only reported if an address somehow falls outside both registries — which, in practice, essentially never happens, since the two together cover the entire address space. Multicast addresses (ff00::/8) are handled separately from both registries, since their behavior comes from RFC 4291's scope field rather than a fixed IANA entry. This tool matches against a snapshot of each registry using longest-prefix match, so a narrow, more specific block (like TEREDO's 2001::/32) correctly takes priority over a broader one it happens to sit inside (2001::/23, IETF Protocol Assignments) — not whichever happens to appear first in a list.
Reading the binary breakdown
The binary row shows all 128 bits of the network address, grouped into nibbles (4 bits, matching one hex digit each) and hex groups (16 bits), with the prefix portion — the first N bits, where N is your prefix length — highlighted in a different color from the remaining address bits, plus a marker at the exact boundary between the two. This is deliberately shown for the network address (remaining bits all zero), not whatever address you typed — entering 2001:db8::1234/64, for example, still shows the binary form of 2001:db8::/64, not the ::1234 you actually typed. The point is seeing exactly where the prefix boundary falls, which matters most when it doesn't land on a clean hex-digit boundary at all: a /101, for example, actually splits a nibble itself — only 1 of that nibble's 4 bits is part of the prefix, the other 3 aren't. (A /104 is a related but different case: it splits a 16-bit hex group exactly in half, 8 bits and 8 bits, but each half is still a pair of *complete* nibbles — it just doesn't align with a full 4-hex-digit group. A /100 splits that same 16-bit group unevenly, 4 bits and 12.) None of these distinctions are visible in hex notation at all — only the binary view shows them. "Remaining address bits" is used deliberately instead of "host bits": the bits after the prefix aren't necessarily host bits at all — a /48, for instance, still has subnet-ID bits ahead of the actual interface ID.
The "IANA 'Globally Reachable' property" row reflects IANA's own registry field of that name, with one deliberate exception to a plain yes/no: some entries, including TEREDO, 6to4, and the deprecated ORCHID allocation, do not have a fixed value in this registry, and this tool says so explicitly — "not specified by IANA" — instead of picking one and presenting it as settled. This field is a registry classification, not a live routability test — it doesn't check anything about your actual network. Multicast addresses don't use this field at all: since they're outside the special-purpose registry, reachability there instead depends on the 4-bit scope value embedded in the address itself (RFC 4291 §2.7, updated by RFC 7346), which this tool reports directly — ff02::1 (Link-Local scope) and ff0e::1 (Global scope) get different scope values rather than one blanket answer for the whole block, and the two reserved scope values (0x0 and 0xF) are handled according to what the RFC actually specifies for each — which isn't the same for both.
Why CSV export is a range, never "everything"
Once you've split a prefix, you can download a range of the resulting subnets as a CSV file — a starting index and how many rows, up to 65,536 per download. There's deliberately no "export all" button: the same reason this tool never lists a full split on screen applies just as much to a file as to the page — a /32 split into /64 is over 4 billion subnets, and generating that as one CSV would be slow at best and could hang the browser tab at worst, all to produce a file most spreadsheet software couldn't usefully open anyway. The estimate below the form updates as you type, before anything is generated, so you always know exactly what you're about to get — including if your requested count would exceed the cap, in which case the estimate says so directly rather than silently downloading a smaller file than expected. One thing worth knowing before opening the file: for very large subnet indexes, import the Index column as text rather than a number — some spreadsheet software silently rounds long numbers to floating-point and loses digits, even though the CSV file itself always has the exact value.
Why /64 specifically
Standard IPv6 addressing practice allocates a /64 as the standard subnet size for most IPv6 LANs, and it's required for conventional SLAAC (which derives a host's address from its interface identifier using the remaining 64 bits). Other prefix lengths are used for specific purposes, though — /127 for point-to-point links, /128 for a single host route — so treat "/64 is standard" as a strong convention for LANs, not a universal rule. Because of that convention, "how many /64s fit in this block" is usually a more useful question than the raw address count, which is why this tool surfaces it directly instead of just an astronomically large total.
Comparing two prefixes: why there's no "partial overlap"
Any two IPv6 prefixes fall into exactly one of four relationships: identical, one fully contains the other, or they don't overlap at all. There's no fifth case where some addresses are shared and some aren't without one prefix fully containing the other — that's not a simplification, it's a genuine mathematical property of how CIDR blocks are defined. Every valid prefix is aligned to a power-of-2 boundary (a /33 always starts at a multiple of 295, never anywhere else), and two ranges that are each aligned that way can only ever nest cleanly inside each other or miss entirely — never overlap halfway. When the comparator reports two prefixes as disjoint but exact sibling halves of the same larger block (e.g. 2001:db8::/32 and 2001:db9::/32, both halves of 2001:db8::/31), it says so directly — that's a mathematical fact about the address ranges, not a recommendation about how to announce them.
Aggregating a list of prefixes
This is a different, broader tool than the comparator's sibling check above: paste in any list of prefixes and it finds the smallest equivalent set that covers exactly the same address space — dropping any prefix that's already fully covered by another one in the list, and merging exact CIDR siblings together, including cascading through multiple levels. Two adjacent /33s can merge into a /32, which might then turn out to be an exact sibling of some other /32 already in the list, cascading into a /31, and so on — this tool follows that chain all the way through, regardless of what order the prefixes were entered in. The result is provably equivalent to the input: every address covered by the original list is covered by the reduced one, and nothing extra is covered that wasn't there before.
Frequently asked questions
Why wasn't my address accepted?
The most common causes: a zone identifier (like %eth0) — not supported here, since it denotes interface scope rather than being part of the address itself — more than one :: in the address, or a group with more than 4 hex digits. The error message currently describes these common causes rather than pinpointing exactly which one applies to your input.
What if I don't include a prefix length?
It's treated as /128 — a single address, not a range. This is mainly useful for quickly getting the compressed/expanded form and reverse DNS name of one specific address.
What does "reverse DNS zone" mean, and why does it only sometimes appear?
It's the ip6.arpa name used to delegate reverse DNS for an entire prefix, rather than one address. Per RFC 3596, that only works cleanly at "nibble boundaries" — prefix lengths that are multiples of 4 — so it's only shown when your prefix length qualifies (a /48 or /64 will show one; a /50 won't).
Why did I get an extra "IPv4-mapped notation" row?
It only appears for addresses in the ::ffff:0:0/96 range, which represent an IPv4 address inside IPv6 (RFC 4291 §2.5.5.2). RFC 5952 §5 recommends showing these with the embedded IPv4 address in dotted-decimal form — ::ffff:192.0.2.1 rather than ::ffff:c000:0201. This is shown as an addition alongside the normal hex form, not a replacement for it — that's also how Python's own IPv6 library handles it internally, keeping its plain compressed form pure hex and exposing the IPv4 interpretation separately.
Why can't the new prefix be the same as, or smaller than, the original?
Splitting only makes smaller, more specific blocks out of a larger one — a /32 can be split into /48s or /64s, but not into a /24 (less specific — that would contain the original, not subdivide it) or another /32 (the same block isn't a split at all, just the original listed as "one subnet of itself"). A /128 can't be split further either, since it's already a single address with nothing smaller to divide it into.
What happens if I jump to an index that's out of range?
You'll get an error stating the valid range (0 up to the subnet count minus one) rather than a silently wrong or clamped result — an out-of-range request is a mistake worth surfacing, not guessing around.
Is the classification always up to date?
It's a snapshot of two IANA registries, not a live lookup — the special-purpose registry (fetched 2025-10-09) and the more general IPv6 Address Space registry (fetched 2025-10-23) — and both do occasionally change. If a very new special-purpose block isn't in that snapshot yet, this tool won't recognize it as that specific type; it typically still reports an accurate, if less specific, classification from the general registry (e.g. "Reserved by IETF") rather than a vague fallback, since the general registry changes far less often. A bare "Reserved / Unassigned" only shows up if an address somehow falls outside every source this tool checks, which in practice essentially never happens.
Why does the "Globally Reachable" property sometimes say "not specified by IANA" instead of yes or no?
Because that's genuinely what the registry says for a small number of entries. TEREDO and 6to4's actual reachability depends on runtime conditions the registry itself doesn't reduce to a fixed answer, so it's recorded as N/A rather than true or false. The deprecated ORCHID allocation (2001:10::/28) is a different case but ends up the same way in practice — its allocation terminated in 2014, and the registry simply lists no current values for it at all. Reporting a guessed true or false in either case would be less accurate than saying so plainly. Worth noting generally: this field is IANA's own registry classification, not a live test of your actual network — it doesn't check anything about your connection or configuration.
Why does the binary view show my network address instead of exactly what I typed?
Because remaining bits being visibly all-zero makes the prefix boundary the whole point of the display, rather than a distraction from whatever bits happened to be in the address you entered. If you want the binary form of the exact address you typed, the "Expanded" row's hex groups convert 1:1 to 4-bit binary nibbles — 2001 is always 0010 0000 0000 0001, regardless of context.
Why is CSV export limited to 65,536 rows per download?
It's a deliberate ceiling, not a technical accident — the same reasoning that keeps this tool from ever listing a full split on screen. 65,536 rows is large enough to cover genuinely common cases (an entire /48 split into /64s, for instance) without risking a computation big enough to freeze the tab. If you need more, export it in multiple ranges by changing the start index.
My spreadsheet is showing rounded or wrong numbers in the Index column for very large indices — is the file broken?
No, the CSV file itself is correct — every index is written out as an exact decimal integer, even ones far larger than a spreadsheet's own numbers normally handle (a /0 split into /128, for example, can have indices up to 39 digits long). The problem is how spreadsheet software interprets that column by default: many will read a long number as floating-point and silently lose precision in the low digits. When importing, tell your spreadsheet software to treat the Index column specifically as text rather than a number, to preserve every digit exactly as written.
Does the comparator's aggregation note mean I should always merge two sibling prefixes into one route?
Not necessarily — it's information, not a recommendation. Two exact sibling halves being mergeable into one supernet is a purely mathematical fact about the address ranges; whether merging them makes sense for your actual routing setup depends on things this tool has no way to know, like whether those two blocks are announced from the same location, or whether your policy or filtering needs them kept separate. Treat the note as "these two happen to be adjacent and aligned," not "you should combine them."
How is "Aggregate a list of prefixes" different from the comparator's aggregation note?
The comparator above only ever answers one narrow question: are these exact two prefixes siblings that happen to form a clean supernet together? The aggregation tool takes an arbitrary list — any number of prefixes, in any order, some possibly redundant or overlapping — and finds the smallest set that covers the same space overall, which can mean cascading through several levels of merging (two /33s merging into a /32 that then turns out to be a sibling of a third prefix, merging again into a /31, and so on). The comparator is a quick check on two specific prefixes; this is the general-purpose version for a real list.
What happens if my list has overlapping or duplicate prefixes, not just adjacent ones?
Both are handled automatically. A prefix that's already fully covered by a broader one elsewhere in the list is dropped as redundant before any merging happens, and exact duplicates collapse to a single entry the same way. You don't need to clean up the list yourself first — paste it as-is.
Does the CSV include every field shown on the page, like the classification?
No — each row is just the subnet's index, its network address, and its CIDR notation (address plus prefix length). Classification, binary form, and reverse DNS are all specific to whatever single address is entered in the calculator above, not something that varies per subnet in a split the same way the address itself does.
Can you see or log what I enter?
No — everything here is calculated locally in your browser and never included in any network request this tool makes.
Working with 32-bit IPv4 addresses instead? Use our IPv4 Subnet Calculator.
Last reviewed: . Methodology: RFC 4291/5952-compliant parsing and compression, RFC 3596 reverse DNS, subnet-splitting arithmetic — all in BigInt throughout (no 32-bit or Number-precision loss, even for indices past Number.MAX_SAFE_INTEGER) — and address classification against snapshots of two IANA registries: the IPv6 Special-Purpose Address Registry (fetched 2025-10-09) and the general IPv6 Address Space registry (fetched 2025-10-23), with scope-aware multicast handling. Verified against RFC test vectors, hand-picked edge cases, randomized property tests, and dedicated test suites covering every entry in both registries, plus five independent cross-checks against Python's own IPv6 library: 500 address-level vectors against its ipaddress module, a separate 50-vector cross-check of the subnet-splitting logic against its subnets() generator, 500 binary-representation vectors against format(int, '0128b'), 1,075 prefix-comparison checks against subnet_of() / overlaps() / supernet(1), and 139 route-aggregation scenarios against collapse_addresses().