1. Calculate an address range and its subdivisions
By the end
- Convert an IPv4 prefix length into a bounded range.
- Distinguish membership from usable host addresses in the stated subnet model.
An IPv4 address contains 32 bits. A /26 prefix fixes 26 bits and leaves 6 to vary, so the block contains 2^6 = 64 addresses. For a block aligned at 192.0.2.0, the final octet runs from 0 through 63. The next address, .64, starts a different /26 block. Counting endpoints inclusively avoids an off-by-one mistake.
In this conventional multi-access IPv4 exercise, the first address identifies the network and the last is its broadcast address. They are not counted as host addresses. Thus the /26 has 62 host addresses, .1 through .62. Do not apply subtract two as a universal rule: /31 and /32 have special behavior, and IPv6 has different conventions.
Increasing the prefix from /26 to /27 splits the block into two equal 32-address blocks. Each child has its own network and broadcast address, so the total conventional host capacity becomes 30 + 30 = 60. Python ipaddress verifies the arithmetic locally. It does not inspect an interface or prove that an address is reachable.
Worked example
Split 192.0.2.0/26 into /27 blocks and locate 192.0.2.40.
- Compute 2^(32-26) = 64, covering .0 through .63.
- Split at the halfway offset 32: .0/27 and .32/27.
- 40 lies between 32 and 63, so it belongs to the second child and is neither endpoint.
from ipaddress import ip_network, ip_address
network = ip_network("192.0.2.0/26")
hosts = list(network.hosts())
children = list(network.subnets(new_prefix=27))
print(network.num_addresses, len(hosts), str(hosts[0]), str(hosts[-1]))
print([str(child) for child in children])
assert network.num_addresses == 64
assert len(hosts) == 62
assert [str(child) for child in children] == ["192.0.2.0/27", "192.0.2.32/27"]
assert ip_address("192.0.2.40") in children[1]
assert ip_address("192.0.2.64") not in network
The parent has 64 total addresses and 62 conventional hosts. The children are 192.0.2.0/27 and 192.0.2.32/27; .40 is a host in the second.
Try it yourself
For 198.51.100.64/27, find the total, broadcast, first and last host, then split into /28 children. Is .80 a member and a conventional host of the second child?
- Show the inclusive range and both child prefixes.
- Answer membership and host eligibility separately.
Reveal the practice solution
There are 32 addresses from .64 through .95; broadcast is .95, and conventional hosts are .65 through .94 (30). Children are .64/28 and .80/28, each with 14 hosts. .80 belongs to the second child but is its network address, so it is not one of those hosts.
from ipaddress import ip_network, ip_address
network = ip_network("198.51.100.64/27")
hosts = list(network.hosts())
children = list(network.subnets(new_prefix=28))
assert network.num_addresses == 32
assert str(network.broadcast_address) == "198.51.100.95"
assert (str(hosts[0]), str(hosts[-1]), len(hosts)) == ("198.51.100.65", "198.51.100.94", 30)
assert [str(n) for n in children] == ["198.51.100.64/28", "198.51.100.80/28"]
assert [len(list(n.hosts())) for n in children] == [14, 14]
assert ip_address("198.51.100.80") in children[1]
assert ip_address("198.51.100.80") not in list(children[1].hosts())
print("32 addresses; 30 conventional hosts; two /28 children with 14 hosts each")
Watch for this mistake: An address can belong to a network without being a conventional host address. Arithmetic membership also says nothing about real connectivity.
Sources and review date
- Python 3.12 — ipaddress
Network membership, num_addresses, hosts, subnets and the special /31 and /32 host behavior. Checked: .
- RFC 5737 — IPv4 Address Blocks Reserved for Documentation
The example ranges 192.0.2.0/24 and 198.51.100.0/24 are for documentation, not targets to contact. Checked: .
Explanations, examples and quiz questions are original KitForma material. These links support technical facts and curriculum alignment.