What do IP addresses look like?

All IP addresses are just binary values. In IPv4, they are 32 bits long. In IPv6 they 128 bits long. But humans aren’t very good with working with long binary numbers, so we created a representation that humans would be more comfortable with.

IPv4 Address Representation

In IPv4, the human friendly representation is called dotted-decimal. The 32 bit value is split into 4 groups of 8 bits each. Each 8 bit group is represented by a decimal value from 0 to 255 (which is 2 to the 8th minus 1, the largest number you can represent with 8 bits). The four values are separated with “dots” (periods). Leading zeros in each field can be removed. So, a typical dotted-decimal representation might be

Somewhere along the way someone thought that decimal (base 10) would be more user-friendly that hexadecimal (base 16), so we wound up with this representation. With the original allocation scheme (class A, class B and class C, with divisions every 8 bits) this kind of made sense. Since CIDR (Classless InterDomain Routing) was introduced we can divide the 32 bits up pretty much anywhere, and now the dotted decimal scheme is a mess – but we’re stuck with it.

The first n bits of an address (the number depends on the size of the IPv4 address block allocated to you) are specified by the ISP (subnet address). The remaining (32-n) bits are an interface identifier (address within a subnet). Originally the first part (subnet address) was either 8 bits (Class A – 16.7 million addresses), 16 bits (Class B – 65,536 addresses) or 24 bits (Class C – 256 addresses), and the interface identifier was 32-n bits long (24, 16 or 8 bits respectively). As we approached the end of life for IPv4, we introduced CIDR to break address blocks up into blocks that were closer to what was actually needed. We can now split the subnet address from the interface identifier almost anywhere in the 32 bits. You might get a /29 block, which would be 8 addresses (two of which can’t be used, and one of which is used by the ISP, leaving 5 usable addresses). This gets very confusing with dotted decimal.

Typical valid IPv4 addresses:

Some invalid IPv4 addresses (in terms of syntax): (no field can exceed 255)

127…1 (only leading zeros can be suppressed, every field must have at least one digit)

123.4.5 (too few fields – must have at least 4) (too many fields – cannot have more than 4)

123.ab.4.5 (only decimal values can be used in IPv4, no hexadecimal)

IPv6 Address Representation

In IPv6, I call the human friendly representation coloned-hex. It would have been a mess to extend the dotted-decimal scheme to IPv6 – would we have 4 groups of 32 bit decimal values from 1 to 4.3 billion, 8 groups of 16 bit decimal values from 0 to 65,535, or 16 groups of 8 bit decimal values from 0 to 255? None of those sound good. Instead they went with 8 groups of 16 bits, with hexadecimal (base 16) values from 0 to ffff (which is 2 to the 16th – 1, or 65,535 in decimal, the largest number that can be represented in 16 bits). Instead of “dots” we now use colons (:). Leading zeros can still be removed. An entire string of 0 fields can be replaced with “::” (but only one such string). So a typical IPv6 address might be written as 2001:470:ed3d:1000::2:1. Just get used to having long IP addresses that may have some letters (a-f) in them. It actually simplifies things later on.

Let’s see what a typical IPv6 address (2001:470:ed3d:1000::2:1) looks like in various versions of dotted decimal:

Four groups of 32 bits, in decimal:


Eight groups of 16 bits, in decimal:


Sixteen groups of 8 bits, in decimal:

Makes “coloned hex” look a lot better, doesn’t it.

The first three 16 bit groups (e.g. 2001:470:ed3d::) are assigned by the ISP. Anywhere from 0 to 16 bits of the fourth group are assigned by the ISP (depending on the size of the IPv6 address block they allocate to you). If you got a /48 block, they don’t assign any bits of the fourth group – you control all 16 bits. If you got a /56 then they assign 8 bits of the fourth group and you control the other 8 bits. If you got a /64, then they assign all 16 bits of that group and you control none of them. The last four 16-bit groups (64 bits) are the interface identifier or the node address within subnet. We will talk much more about interface identifiers later.

Regardless, the first 64 bits are really the subnet address, and the last 64 bits are the interface identifier. All IPv6 subnets are /64, period. Much simpler.

The Best Current Operator Practices recommendation is to give all business users a /48 block (65,536 possible subnets, each with its own /64 block). Home users are supposed to get at least a /60 (16 possible subnets) and ideally a /56 (256 possible subnets). It is entirely reasonable to give all customers their own /48. There are enough /48s in the current block marked for allocation (2000::/3) to give every human alive today over 5,000 of them. But, marketing people at ISPs want to make it look like business customers are getting preferential treatment. Unfortunately, many ISPs today are giving home customers only a single /64 (one subnet). As IPv6 evolves this will be a problem. People will want one subnet for mom and dad, a different one for their kids, another for all of their smart devices, with firewalls controlling what can go between the subnets.

One good solution is to allocate only one /64 to home users, but actually set aside an entire /56 or even /48 for them (most of which is unallocated) to allow them to expand their allocation in the future, without having to renumber.

Some valid IPv6 addresses:

fe80::1:2:3:4 – link local address (valid only in the local link or subnet)

2001:470:ed3a:1000::2:1 – normal global address

2001:470:ed3d:: – everything after the :: is zeros (equivalent to 2001:470:ed3d:0:0:0:0:0)

::1 – 127 bits of zero followed by 1 bit of one, everything before the :: is zeros, equivalent to 0:0:0:0:0:0:0:1. The IPv6 loopback address (like

:: – 128 bits of zero, everything before and after the :: is zeros. Equivalent to 0:0:0:0:0:0:0:0 (the unspecified address)

Some invalid IPv6 addresses (with regards to syntax):

2001::1:2::5 – can’t have two :: in one address (ambiguous)

2001:470:ed3a:10000:1:2:3:4 – no field can exceed ffff

2001:470:ed3a:1000:1:2:3:4:5 – too many fields (can’t be more than 8)

2001:470:ed3a:1000:1:2:3 – too few fields (can’t be less than 8, without ::)

2001:470:ed3g:1000::2:1 – g is not a valid hex digit (only a-f)