X Xerobit

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...

Mian Ali Khalid · · 5 min read
Use the tool
Subnet / CIDR Calculator
Calculate IPv4 subnets — network, broadcast, usable range, wildcard mask. Input CIDR (/24) or dotted mask (255.255.255.0). Binary visualization.
Open Subnet / CIDR Calculator →

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

PrefixMaskHostsUse case
/8255.0.0.016,777,214Large enterprise / 10.0.0.0/8
/16255.255.0.065,534VPC default
/24255.255.255.0254Office network
/25255.255.255.128126Split a /24 in two
/26255.255.255.19262Department subnet
/28255.255.255.24014Small subnet
/30255.255.255.2522Point-to-point link
/31255.255.255.2542P2P (no broadcast)
/32255.255.255.2551Host 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 posts

Related tool

Subnet / CIDR Calculator

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.