CIDR (Classless Inter-Domain Routing) notation is a compact representation of IP addresses and their associated routing prefix. Instead of using subnet masks like 255.255.255.0, CIDR uses a simpler format: IP_address/prefix_length (e.g., 192.168.1.0/24).
The number after the slash represents the number of bits in the network portion of the address. For example:
192.168.1.0/24 means:
- First 24 bits are network address
- Last 8 bits (32-24) are host addresses
- Equivalent to subnet mask 255.255.255.0
Let's break down some common CIDR blocks:
10.0.0.0/8:
- Network portion: 10.0.0.0
- Host range: 10.0.0.1 - 10.255.255.254
- Total addresses: 16,777,214
172.16.0.0/12:
- Network portion: 172.16.0.0
- Host range: 172.16.0.1 - 172.31.255.254
- Total addresses: 1,048,574
Here's a Python function to calculate the network range from a CIDR:
import ipaddress
def cidr_info(cidr):
network = ipaddress.ip_network(cidr, strict=False)
print(f"Network: {network.network_address}")
print(f"Broadcast: {network.broadcast_address}")
print(f"Host range: {network.network_address+1} - {network.broadcast_address-1}")
print(f"Total hosts: {network.num_addresses-2}")
cidr_info("192.168.1.0/24")
When working with AWS, GCP, or Azure, you'll often see these CIDR ranges:
VPC default range: 10.0.0.0/16 (65,534 hosts)
Subnet typical range: 10.0.1.0/24 (254 hosts)
Kubernetes pod network: 10.244.0.0/16
Service network: 10.96.0.0/12
When designing networks, it's crucial to avoid overlaps. Here's how to check:
def check_overlap(cidr1, cidr2):
n1 = ipaddress.ip_network(cidr1)
n2 = ipaddress.ip_network(cidr2)
return n1.overlaps(n2)
print(check_overlap("10.0.0.0/16", "10.0.1.0/24")) # Returns True
CIDR (Classless Inter-Domain Routing) might seem like just a "/" followed by a number, but it's actually a powerful way to represent IP addresses and their routing prefixes. Let me show you what really happens when you see something like 192.168.1.0/24.
// Binary representation of 192.168.1.0/24
IP: 11000000.10101000.00000001.00000000
Mask: 11111111.11111111.11111111.00000000
Network:11000000.10101000.00000001.00000000
The number after the slash (prefix length) indicates how many bits are fixed as the network portion. Here's how it translates:
CIDR | Subnet Mask | Usable Hosts |
---|---|---|
/24 | 255.255.255.0 | 254 |
/25 | 255.255.255.128 | 126 |
/26 | 255.255.255.192 | 62 |
Here's my mental shortcut for /24 to /30 ranges:
1. Remember the key numbers: 0, 128, 192, 224, 240, 248, 252, 254, 255
2. For /25 and above, subtract 256 - the last octet value to get block size
Example: /26 = 255.255.255.192 → 256-192=64 → block size=64
3. Valid subnets increment by the block size
Here's how you can work with CIDR in different programming languages:
Python example using ipaddress module:
import ipaddress
network = ipaddress.IPv4Network('192.168.1.0/24')
print(f"Network: {network.network_address}")
print(f"Broadcast: {network.broadcast_address}")
print(f"Hosts: {network.num_addresses - 2}")
JavaScript implementation:
function cidrToRange(cidr) {
const [ip, prefix] = cidr.split('/');
const mask = 0xffffffff << (32 - parseInt(prefix));
const start = (ipToLong(ip) & mask) + 1;
const end = start + (1 << (32 - parseInt(prefix))) - 3;
return [longToIp(start), longToIp(end)];
}
In real-world scenarios, you'll often see these CIDR notations:
- /32 - Single host (used in firewall rules)
- /31 - Point-to-point links (RFC 3021)
- /30 - Common for WAN links (2 usable hosts)
- /29 - Small networks (6 usable hosts)
- /28 - Medium networks (14 usable hosts)
- /24 - Default for many private networks (254 hosts)
When you need to combine or split networks:
# Python example - creating subnets
base_net = ipaddress.IPv4Network('192.168.0.0/16')
subnets = list(base_net.subnets(prefixlen_diff=8))
# Creates 256 /24 networks from a /16
Remember that supernetting (combining networks) requires contiguous address space with matching prefix bits.