An IP address is 32 bits dressed up as four decimal numbers. Once you can see the binary underneath, subnetting stops being magic — start here.
Why: an IPv4 address is really 32 binary digits, written as four 8-bit "octets" in decimal so humans can read it — every subnetting trick is just bit manipulation on those 32 bits. When: think in binary whenever masks or subnets are involved. Where: each octet ranges 0–255 because 8 bits hold 256 values.
192 . 168 . 1 . 10
||||||| ||||||| ||||||| |||||||
11000000 10101000 00000001 00001010 <- the real address (32 bits)
Each octet = 8 bits = 0..255
Bit values: 128 64 32 16 8 4 2 1
192 = 128 + 64 -> 11000000Why: you rarely convert by hand in practice — Python’s built-in ipaddress module turns dotted-decimal into its integer/binary form and back, so you can check your reasoning instantly. When: use it to verify subnetting by eye until the binary is second nature. Where: the module ships with Python, so there is nothing to install.
import ipaddress
ip = ipaddress.ip_address("192.168.1.10")
print(int(ip)) # 3232235786 — the 32-bit value as an integer
print(f"{int(ip):032b}") # 11000000101010000000000100001010
# Back from binary/integer:
print(ipaddress.ip_address(3232235786)) # 192.168.1.10Why: not every address is usable on the internet — RFC 1918 reserves private ranges for internal networks (which NAT later translates), and other ranges are reserved for loopback and link-local. When: pick addresses from the private ranges for any LAN you build. Where: knowing these by heart prevents addressing mistakes that break connectivity.
PRIVATE (RFC 1918 — internal use, not routable on the internet):
10.0.0.0/8 10.0.0.0 – 10.255.255.255
172.16.0.0/12 172.16.0.0 – 172.31.255.255
192.168.0.0/16 192.168.0.0 – 192.168.255.255
SPECIAL:
127.0.0.0/8 loopback (127.0.0.1 = "this machine")
169.254.0.0/16 link-local (APIPA — no DHCP was reached)