Every time a computer sends an IPv4 packet, it decides whether the destination is on the local network or must go through a router. That decision is a single bitwise AND. Understanding it makes subnetting, CIDR notation, and firewall rules far less mysterious.

IPv4 Addresses Are 32-Bit Numbers

The familiar dotted form 192.168.10.77 is four bytes written in decimal. In binary:

192      .168      .10       .77
11000000 .10101000 .00001010 .01001101

As one 32-bit integer that is 0xC0A80A4D, or 3,232,238,157. Routers and operating systems work with this integer form.

What a Subnet Mask Is

A subnet mask is also 32 bits. It has a run of 1 bits on the left followed by 0 bits on the right. The 1 bits mark the network part of an address and the 0 bits mark the host part.

MaskBinaryCIDR prefixHost bits
255.0.0.011111111.00000000.00000000.00000000/824
255.255.0.011111111.11111111.00000000.00000000/1616
255.255.255.011111111.11111111.11111111.00000000/248
255.255.255.19211111111.11111111.11111111.11000000/266
255.255.255.25211111111.11111111.11111111.11111100/302

The CIDR prefix (/24) is simply the number of leading 1 bits.

Finding the Network Address With AND

AND the address with the mask. Every host bit is forced to 0 and every network bit is kept:

Address  11000000.10101000.00001010.01001101   192.168.10.77
Mask     11111111.11111111.11111111.00000000   255.255.255.0
AND      11000000.10101000.00001010.00000000   192.168.10.0

The network address is 192.168.10.0/24. You can check the last octet in the Bitwise AND Calculator: 77 & 0 = 0.

A /26 example shows why binary matters when the mask doesn’t fall on a byte boundary:

Address last octet   77  = 01001101
Mask last octet     192  = 11000000
AND                  64  = 01000000

So 192.168.10.77/26 belongs to the network 192.168.10.64/26.

Same Subnet or Not?

Two hosts are on the same subnet when their network addresses match:

(ipA & mask) == (ipB & mask)

With a /26 mask, 192.168.10.77 and 192.168.10.100 are on the same subnet (100 & 192 = 64). But 192.168.10.130 is not, because 130 & 192 = 128. If the check fails, the operating system sends the packet to its default gateway instead.

Broadcast Address and Host Range

The broadcast address sets every host bit to 1. Compute it with OR and the inverted mask:

broadcast = network | ~mask

For 192.168.10.64/26, the inverted mask’s last octet is 00111111 (63), so the broadcast address is 192.168.10.127. Usable hosts run from .65 to .126. A subnet with h host bits has 2^h − 2 usable addresses (the network and broadcast addresses are reserved), except /31 point-to-point links and /32 single hosts.

PrefixAddressesUsable hosts
/24256254
/25128126
/266462
/273230
/3042

Subnet Math in Code

import ipaddress

def to_int(ip: str) -> int:
    a, b, c, d = map(int, ip.split("."))
    return (a << 24) | (b << 16) | (c << 8) | d

def to_ip(n: int) -> str:
    return ".".join(str((n >> s) & 0xFF) for s in (24, 16, 8, 0))

prefix = 26
mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF
ip = to_int("192.168.10.77")

network = ip & mask
broadcast = network | (~mask & 0xFFFFFFFF)
print(to_ip(mask), to_ip(network), to_ip(broadcast))
# 255.255.255.192 192.168.10.64 192.168.10.127

# The standard library does the same thing:
print(ipaddress.ip_interface("192.168.10.77/26").network)  # 192.168.10.64/26

Note the & 0xFFFFFFFF after the left shift and after NOT. Python integers have no fixed width, so you must mask back to 32 bits, as explained in Bitwise Operators in Python.

In JavaScript, remember to convert with >>> 0, because results above 2^31 turn negative:

const mask = (0xFFFFFFFF << (32 - 26)) >>> 0;   // 4294967232 (255.255.255.192)

Wildcard Masks

Some router configurations, such as Cisco access lists, use wildcard masks. A wildcard mask is the bitwise NOT of the subnet mask: 0.0.0.63 for a /26. A 0 bit means “must match” and a 1 bit means “don’t care”. It is the same information, just inverted, which you can confirm with the Bitwise NOT Calculator at 8-bit width.

What About IPv6?

IPv6 addresses are 128 bits, and prefixes work the same way: 2001:db8:abcd:12::/64 means the first 64 bits are the network. The AND logic is identical. The numbers are just four times longer, which is one reason IPv6 is always written in hexadecimal.

Summary

  • Network address = address & mask.
  • Broadcast address = network | ~mask.
  • Same subnet when (a & mask) == (b & mask).
  • A CIDR prefix is the count of leading 1 bits in the mask.

Once you see subnets as bitwise operations on 32-bit integers, every subnetting question becomes a matter of lining up the bits.