Intuition What this page is
The parent note taught the rules of IPv6 addresses. Rules are easy to read and easy to misapply. Here we grind through every kind of address you can meet , so that when an exam or a real router config throws one at you, you have already seen its twin. Nothing new is assumed — we rebuild each idea as we hit it.
Before touching a single address, let us re-anchor the three tools we will keep using, in plain words:
Definition The three tools, from zero
A bit is one on/off switch: it is either 0 or 1 . Nothing more.
A hex digit (hexadecimal digit) is a single symbol from 0 1 2 3 4 5 6 7 8 9 a b c d e f. It stands for a number from 0 to 15 . Because 16 = 2 4 , one hex digit packs exactly 4 bits . See Hexadecimal and Binary Number Systems .
A hextet (our word for one IPv6 group) is 4 hex digits = 16 bits . An IPv6 address is 8 hextets , so 8 × 16 = 128 bits.
WHY hex and not decimal? Decimal digits don't line up with bits (10 is not a power of 2 ), so you can't cleanly say "this digit = these 4 bits". Hex does line up, so reading structure off the address is possible. That is the whole reason IPv6 chose it.
Every IPv6 address question is really one of these cells. The examples below are labelled by cell letter so you can see the coverage is complete.
Cell
Scenario class
The tricky part
Covered by
A
One long zero-run
Where does :: go?
Ex 1
B
Two zero-runs, tie in length
Which run wins?
Ex 2
C
Two zero-runs, one longer
:: on the longer only
Ex 3
D
Zero-run of length 1
Is :: even allowed?
Ex 4
E
Degenerate / all-zero-ish (loopback, unspecified)
Everything collapses
Ex 5
F
Expand a compressed address back to full
Reverse the rules, count to 8
Ex 6
G
Illegal address — spot & fix
Two ::, over-long hextet
Ex 7
H
Real-world word problem (prefix / interface split, /64)
Where is the boundary?
Ex 8
I
Exam twist (counting addresses in a prefix, powers of 2)
Arithmetic, not just formatting
Ex 9
2001:0db8:0000:0000:0000:0000:1428:57ab
Forecast: before reading on — guess how many hextets the :: will swallow, and what the final string looks like.
Step 1 — split into the 8 hextets and label them.
h1..h8 = 2001 , 0db8 , 0000 , 0000 , 0000 , 0000 , 1428 , 57ab
Why this step? You can only apply the rules once you can see the 8 groups. Everything downstream is bookkeeping on this list.
Step 2 — leading-zero rule, per hextet. Drop zeros only at the front of each group: 0db8→db8, 0000→0, 1428→1428, 57ab→57ab.
Result: 2001:db8:0:0:0:0:1428:57ab.
Why this step? 0db8 and db8 are the same 16-bit value; the leading 0 carries no information. We never drop a trailing or middle zero (1428 keeps its 0).
Step 3 — find the longest run of all-zero hextets. Hextets h3–h6 are 0 0 0 0 — a run of 4 . That is the longest (only) run.
Why this step? :: is allowed once, so it should be spent where it saves the most.
Step 4 — replace that run with ::.
2001:db8::1428:57ab
Why this step? :: means "insert enough all-zero hextets to reach 8 total". Here it stands for 4 zero hextets.
Verify: count what remains around ::. Left of ::: 2001, db8 = 2 hextets. Right: 1428, 57ab = 2 hextets. So :: must supply 8 − 2 − 2 = 4 hextets — exactly the four zeros we removed. ✅ The address round-trips.
2001:0db8:0000:0000:0001:0000:0000:0001
Forecast: there are two zero-runs. Guess which one gets the ::.
Step 1 — leading zeros. 2001:db8:0:0:1:0:0:1.
Why? Same as before; strip front zeros so the structure is visible.
Step 2 — list the zero-runs. Run X = h3–h4 (0 0, length 2). Run Y = h6–h7 (0 0, length 2). It's a tie .
Why this step? :: may appear only once, so among competing runs we must pick exactly one.
Step 3 — tie-break: compress the FIRST longest run, leave the other written out.
2001:db8::1:0:0:1
Why this step? The standard (RFC 5952) says: when lengths tie, :: goes on the leftmost run. The other run stays explicit as 0:0.
Verify: left of :: = 2001,db8 (2). Right of :: = 1,0,0,1 (4). :: supplies 8 − 2 − 4 = 2 hextets — matches Run X's two zeros. ✅
Why NOT 2001:db8:0:0:1::1? That would put :: on Run Y and write Run X out. It represents the same address, but the convention forbids it — always pick the leftmost of tied runs.
2001:0000:0000:00a3:0000:0000:0000:1234
Forecast: one run has 2 zeros, another has 3. Which gets ::, and how many hextets does it eat?
Step 1 — leading zeros. 2001:0:0:a3:0:0:0:1234.
Why? Front-zero strip; note 00a3→a3.
Step 2 — list runs. Run X = h2–h3 (length 2). Run Y = h5–h7 (length 3).
Why this step? We need the lengths to decide.
Step 3 — :: goes on the LONGEST run (Run Y).
2001:0:0:a3::1234
Why this step? Longer run ⇒ more hextets saved ⇒ shorter, standard form. Run X stays as 0:0.
Verify: left of :: = 2001,0,0,a3 (4). Right = 1234 (1). :: supplies 8 − 4 − 1 = 3 — exactly Run Y's three zeros. ✅
2001:db8:1:0:5:6:7:8
Forecast: there is exactly one zero hextet. Should you write :: here?
Step 1 — leading zeros. Already minimal: 2001:db8:1:0:5:6:7:8.
Step 2 — the only zero-run is h4, length 1.
Why this step? We check whether :: helps.
Step 3 — do NOT use :: for a single zero group.
2001:db8:1:0:5:6:7:8
Why this step? :: replaces 0 with the same number of characters (:: is not shorter than :0: in effect) and the standard (RFC 5952 §4.2.2) says :: must not be used to shorten a single 0 hextet . It is only for runs of two or more .
Verify: the address still has 8 hextets and one colon between each — 7 colons total, no ::. ✅ Legal and canonical.
Common mistake "Any zero group should become
::"
Why it feels right: :: looks tidier.
Why it's wrong: for a lone 0 it saves nothing and violates the canonical form. :: earns its place only on runs of length ≥ 2 .
Worked example Write the loopback, the unspecified address, and confirm
fe80::/10
Forecast: what happens when almost every hextet is zero?
Part (a) — loopback. Full form: 0000:0000:0000:0000:0000:0000:0000:0001.
Step 1 — leading zeros: 0:0:0:0:0:0:0:1.
Step 2 — the run of seven leading zeros collapses:
::1
Why? Seven zero hextets are one run; :: swallows all seven. This is IPv6's 127.0.0.1. See OSI & TCP-IP Model — Network Layer for where loopback lives.
Part (b) — unspecified address. Full form: all zeros, 0000:...:0000.
All eight hextets are zero, so:
::
Why? :: alone means "8 zero hextets" — used as "I have no address yet" during boot (see DHCP and SLAAC ).
Part (c) — link-local prefix fe80::/10. The address fe80:0000:0000:0000:... starts with fe80.
fe80:: (prefix)
Why the /10? fe80 in binary is 1111 1110 1000 0000. The prefix is defined by the first 10 bits 1111 1110 10, hence /10. These are auto-assigned and not routable off the link.
Verify (a): ::1 → left of :: = nothing (0 hextets), right = 1 (1 hextet), so :: supplies 8 − 0 − 1 = 7 zeros → full is 0:0:0:0:0:0:0:1. ✅
Verify (c): fe80 = f = 15 , e = 14 , 8 = 8 , 0 = 0 ⇒ bits 1111,1110,1000,0000. First 10 bits 1111111010. ✅
2001:db8::ff:0:1234 to its full 8-hextet form
Forecast: how many hextets does :: hide here?
Step 1 — count the explicit hextets on each side of ::.
Left: 2001, db8 → 2 hextets. Right: ff, 0, 1234 → 3 hextets.
Why this step? :: fills the gap to reach 8, so we must know how many are already present.
Step 2 — compute the hidden count. 8 − 2 − 3 = 3 zero hextets.
Why this step? This is the only unknown; total must be 8.
Step 3 — restore each hextet to full 4-hex-digit width.
2001→2001, db8→0db8, then three 0000, then 00ff, 0000, 1234.
2001:0db8:0000:0000:0000:00ff:0000:1234
Why this step? Full form pads every group to 4 digits — this is what a machine stores internally.
Verify: count groups: 2001 db8 0000 0000 0000 00ff 0000 1234 = 8 hextets = 128 bits. ✅ Note the explicit 0 between ff and 1234 was NOT part of the :: — only genuinely consecutive omitted zeros are.
:: ate everything, including the visible :0:"
Why it feels right: you see zeros both inside :: and written as 0.
Why it's wrong: an address may show :: and a separate explicit 0 hextet. Only the run replaced by :: is hidden; a written 0 is a group you must keep. That's why 8 − 2 − 3 = 3 , not more.
Worked example Which are illegal, and why? Fix each.
(i) 2001:db8::25de::cade (ii) 2001:db8:12345:0:0:0:0:1 (iii) 2001::0db8:0:0:1
Forecast: guess which fail before reading.
Step 1 — check (i) for multiple ::. It has two ::. Illegal.
Why? Each :: means "unknown number of zero hextets". With two gaps the parser cannot split the missing zeros between them — ambiguous. Only one :: per address.
Fix: pick the longer zero-run for ::, write the other explicitly, e.g. 2001:db8:0:25de::cade (compressing whichever run is longer; here both gaps were length 2 originally, so 2001:db8::25de:0:0:cade is one valid canonical form).
Step 2 — check (ii) for an over-long hextet. 12345 has 5 hex digits. Illegal.
Why? A hextet is 16 bits = at most 4 hex digits (max value ffff = 65535). 12345 needs 17 bits. Impossible.
Fix: it's a typo; a legal group is at most ffff.
Step 3 — check (iii). 2001::0db8:0:0:1 — one ::, all hextets ≤ 4 digits. Legal , though not canonical (should strip 0db8→db8): 2001::db8:0:0:1.
Why "not canonical"? The address is valid but the leading-zero rule wasn't applied. RFC 5952 wants the shortest standard spelling.
Verify: In (iii), left of :: = 2001 (1), right = db8,0,0,1 (4), so :: = 8 − 1 − 4 = 3 zero hextets. 1 + 3 + 4 = 8 . ✅ Legal.
Worked example An ISP gives you the prefix
2001:db8:acad:1::/64. What is the network part, what is the device (interface) part, and can two different devices share this prefix?
Forecast: where does the /64 boundary fall in the 128 bits?
Step 1 — read the /64. The number after / counts how many leading bits are the network prefix . Here 64 of the 128 bits are fixed by the network.
Why this step? CIDR notation prefix/n (same idea as IPv4 Addressing & CIDR and Subnetting ) tells you the split point.
Step 2 — locate the boundary in hextets. Each hextet is 16 bits, so 64/16 = 4 hextets are network. Network hextets = 2001, db8(=0db8), acad, 0001. The remaining 4 hextets are the interface ID (which device).
network prefix, 64 bits 2001:0db8:acad:0001 interface ID, 64 bits ????:????:????:????
Why this step? 64 = 4 × 16 , so the boundary sits exactly at a colon — convenient. This 64/64 split is what makes SLAAC (auto-config, see DHCP and SLAAC ) work.
Step 3 — can two devices coexist? Yes. They share the first 64 bits (same network) but choose different interface IDs. Example devices:
2001:db8:acad:1::10 and 2001:db8:acad:1::20.
Why this step? The interface ID distinguishes hosts on the same link; broadcast isn't needed because IPv6 uses multicast/anycast instead (see Multicast vs Broadcast vs Anycast ).
Verify: how many distinct interface IDs fit in 64 bits? 2 64 ≈ 1.8 × 1 0 19 — vastly more than any single link needs. ✅ Two devices are trivially accommodated.
Worked example How many IPv6 addresses does a
/48 prefix contain, and how many /64 subnets fit inside it?
Forecast: guess the exponents before computing.
Step 1 — count the host bits in a /48. Total 128 bits, prefix 48 bits fixed ⇒ 128 − 48 = 80 free bits.
Why this step? Free (non-prefix) bits are the ones that can vary, so they count the addresses.
Step 2 — addresses = 2 free bits .
2 80 ≈ 1.2089 × 1 0 24
Why this step? Each free bit is an independent on/off choice; n bits ⇒ 2 n combinations (multiplication principle — the same reason IPv4 has 2 32 ).
Step 3 — how many /64 subnets inside a /48? Subnet bits = 64 − 48 = 16 . Number of /64s = 2 16 = 65536 .
Why this step? Going from a /48 to /64 we pin down 16 more bits; each pattern of those 16 bits is one subnet.
Verify: 2 16 = 65536 ; and each /64 holds 2 64 addresses, so 2 16 × 2 64 = 2 80 — matches Step 2. ✅ Consistency check closes the loop.
Recall Fast self-test (cover the answers)
:: may appear how many times per address? ::: Exactly once.
Minimum zero-run length that :: should compress? ::: Two hextets (never a lone 0).
On a tie between two equal zero-runs, which gets ::? ::: The leftmost (first) one.
Max hex digits in one hextet, and why? ::: 4, because a hextet is 16 bits and 16/4 = 4 .
In 2001:db8::1428:57ab, how many zero hextets does :: hide? ::: 8 − 2 − 2 = 4 .
How many /64 subnets fit in a /48? ::: 2 16 = 65536 .
How many addresses in a /48? ::: 2 80 ≈ 1.2 × 1 0 24 .
Mnemonic The compression checklist
"Strip the fronts, find the longest run, :: it once (only if two-plus), count back to eight."
candidate for double-colon