CIDR Subnet Calculator — Calculate Network, Broadcast, and Host Range
Calculate subnet network address, broadcast address, host range, and usable IP count from a CIDR notation like 192.168.1.0/24. Includes Python and JavaScript implementations...
CIDR notation (192.168.1.0/24) encodes both the network address and the subnet mask. From these two values you can calculate the full subnet details: network address, broadcast, host range, and usable count.
Use the Subnet Calculator to calculate all subnet details instantly.
CIDR notation basics
192.168.1.0/24
│ └── Prefix length: 24 bits are the network part
└────────────── IP address
/24 = subnet mask 255.255.255.0
→ 24 bits for network, 8 bits for hosts
→ 2^8 = 256 total addresses
→ 2^8 - 2 = 254 usable hosts (subtract network + broadcast)
Calculating subnet details
Network address
AND the IP address with the subnet mask:
IP: 11000000.10101000.00000001.01000101 (192.168.1.69)
Mask: 11111111.11111111.11111111.00000000 (255.255.255.0)
AND: 11000000.10101000.00000001.00000000 (192.168.1.0)
Broadcast address
OR the network address with the inverse mask (wildcard mask):
Network: 11000000.10101000.00000001.00000000 (192.168.1.0)
Wildcard: 00000000.00000000.00000000.11111111 (0.0.0.255)
OR: 11000000.10101000.00000001.11111111 (192.168.1.255)
Host range
- First usable host: network address + 1 =
192.168.1.1 - Last usable host: broadcast - 1 =
192.168.1.254
Python implementation
import ipaddress
def subnet_info(cidr: str) -> dict:
net = ipaddress.IPv4Network(cidr, strict=False)
return {
'network': str(net.network_address),
'broadcast': str(net.broadcast_address),
'subnet_mask': str(net.netmask),
'wildcard_mask': str(net.hostmask),
'prefix_length': net.prefixlen,
'total_addresses': net.num_addresses,
'usable_hosts': net.num_addresses - 2 if net.prefixlen < 31 else 0,
'first_host': str(net.network_address + 1) if net.prefixlen < 31 else str(net.network_address),
'last_host': str(net.broadcast_address - 1) if net.prefixlen < 31 else str(net.broadcast_address),
'host_range': f"{net.network_address + 1} – {net.broadcast_address - 1}",
}
# Examples:
print(subnet_info('192.168.1.0/24'))
# {'network': '192.168.1.0', 'broadcast': '192.168.1.255',
# 'subnet_mask': '255.255.255.0', 'prefix_length': 24,
# 'total_addresses': 256, 'usable_hosts': 254, ...}
print(subnet_info('10.0.0.0/8'))
# 16,777,216 total, 16,777,214 usable
# List all subnets when dividing a network:
parent = ipaddress.IPv4Network('10.0.0.0/16')
subnets = list(parent.subnets(new_prefix=24))
print(f"{len(subnets)} /24 subnets") # 256 /24 subnets
JavaScript implementation
function subnetInfo(cidr) {
const [ip, prefix] = cidr.split('/');
const prefixLen = parseInt(prefix);
const ipParts = ip.split('.').map(Number);
const ipInt = ipParts.reduce((acc, octet) => (acc << 8) + octet, 0) >>> 0;
const maskInt = prefixLen === 0 ? 0 : (~0 << (32 - prefixLen)) >>> 0;
const wildcardInt = (~maskInt) >>> 0;
const networkInt = (ipInt & maskInt) >>> 0;
const broadcastInt = (networkInt | wildcardInt) >>> 0;
const intToIp = n => [
(n >>> 24) & 255,
(n >>> 16) & 255,
(n >>> 8) & 255,
n & 255,
].join('.');
const totalAddresses = Math.pow(2, 32 - prefixLen);
const usableHosts = prefixLen < 31 ? totalAddresses - 2 : 0;
return {
network: intToIp(networkInt),
broadcast: intToIp(broadcastInt),
subnetMask: intToIp(maskInt),
prefixLength: prefixLen,
totalAddresses,
usableHosts,
firstHost: intToIp(networkInt + 1),
lastHost: intToIp(broadcastInt - 1),
};
}
subnetInfo('192.168.1.0/24');
// { network: '192.168.1.0', broadcast: '192.168.1.255',
// subnetMask: '255.255.255.0', usableHosts: 254, ... }
Common subnet reference
| Prefix | Mask | Hosts | Use case |
|---|---|---|---|
| /8 | 255.0.0.0 | 16,777,214 | Large enterprise / 10.0.0.0/8 |
| /16 | 255.255.0.0 | 65,534 | VPC default |
| /24 | 255.255.255.0 | 254 | Office network |
| /25 | 255.255.255.128 | 126 | Split a /24 in two |
| /26 | 255.255.255.192 | 62 | Department subnet |
| /28 | 255.255.255.240 | 14 | Small subnet |
| /30 | 255.255.255.252 | 2 | Point-to-point link |
| /31 | 255.255.255.254 | 2 | P2P (no broadcast) |
| /32 | 255.255.255.255 | 1 | Host route |
Check if IP is in subnet
import ipaddress
def is_in_subnet(ip: str, cidr: str) -> bool:
return ipaddress.ip_address(ip) in ipaddress.IPv4Network(cidr, strict=False)
is_in_subnet('192.168.1.100', '192.168.1.0/24') # True
is_in_subnet('192.168.2.1', '192.168.1.0/24') # False
is_in_subnet('10.0.0.50', '10.0.0.0/8') # True
Related tools
- Subnet Calculator — calculate subnet details online
- Private IP Ranges — RFC 1918 address ranges
- Subnet Mask Explained — how subnet masks work
Related posts
- Private IP Address Ranges, Subnets, and CIDR Notation Explained — The three RFC 1918 private ranges, what CIDR notation actually means, subnet mas…
- CIDR Notation Explained — What /24, /16, /8 Mean in IP Addresses — CIDR notation is the slash number after an IP address — /24, /16, /8. It specifi…
- DHCP IP Allocation — How Dynamic IP Assignment Works — DHCP (Dynamic Host Configuration Protocol) automatically assigns IP addresses, s…
- Private IP Address Ranges — RFC 1918 and Reserved IP Blocks — Private IP address ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) are not ro…
- Subnet Mask Explained — How Subnetting and Network Masks Work — A subnet mask separates the network portion from the host portion of an IP addre…
Related tool
Calculate IPv4 subnets — network, broadcast, usable range, wildcard mask. Input CIDR (/24) or dotted mask (255.255.255.0). Binary visualization.
Written by Mian Ali Khalid. Part of the Dev Productivity pillar.