What an "IP address as a number" actually is
An IPv4 address is a 32-bit unsigned integer. The dotted-quad notation we usually see — 192.0.2.1 — is one specific way to render those 32 bits as four 8-bit pieces in decimal. The same bits can be shown as a single decimal integer (3221225985), as hex (0xC0000201), as binary (11000000.00000000.00000010.00000001), or even as a single octal number. They all represent the same address; what changes is how humans read it.
An IPv6 address is a 128-bit unsigned integer. The familiar colon-hex notation — 2606:4700:4700::1111 — is one specific text form. The integer is too large to fit in a standard 64-bit number (it would overflow), so languages like JavaScript represent it as a BigInt; languages like Python and Java handle arbitrary-precision integers natively.
Real-world reasons to do this conversion
Range comparisons and CIDR membership tests
"Is 198.51.100.42 inside 198.51.100.0/24?" is much simpler as integer math than as dotted-decimal string math. Convert both sides to integers, compute the start and end of the CIDR range, and check start <= ip && ip <= end. Every CIDR library does this under the hood.
Compact database storage
Storing IPv4 as a BIGINT column (4 bytes signed, or 4 bytes unsigned with a check constraint) is more compact than VARCHAR(15) and far more efficient for range queries. IPv6 fits in a BINARY(16) column, but you can index integer or binary representations and get sub-millisecond CIDR-membership lookups even on tens of millions of rows. PostgreSQL natively has the inet and cidr types that handle this elegantly; other databases require manual conversion.
Bit manipulation in low-level networking
Computing the network address of 10.42.83.7/22 requires masking the host bits — that's a single bitwise-AND on the integer representations, but a multi-step parse-then-recombine on the dotted form. Anyone writing routing-table code, packet filters, or firewall rules works in the integer view.
Decoding obscured URLs
Spam and phishing sometimes uses IP-as-decimal URLs to evade naive URL filters. http://3221225985/ is the same as http://192.0.2.1/ to a browser, but a regex looking for dotted-quad won't catch it. If you're analyzing suspicious links, the decimal-to-IP conversion is a daily move.
The representations explained
Canonical (dotted-quad / colon-hex)
What humans normally use. 192.0.2.1 for IPv4, 2606:4700:4700::1111 for IPv6 in its compressed form.
Fully expanded (IPv6 only)
IPv6 has compression rules that let you write 2606:4700:4700::1111 instead of 2606:4700:4700:0000:0000:0000:0000:1111. The expanded form is what comparison algorithms and some APIs need. We show both.
Single decimal integer
The 32 bits (or 128 bits) interpreted as one unsigned base-10 number. IPv4 maxes out at 4,294,967,295. IPv6 maxes out at 340,282,366,920,938,463,463,374,607,431,768,211,455 — a 39-digit number.
Hexadecimal
Each byte as a two-digit hex pair, no separators. IPv4 fits in 8 hex digits. IPv6 fits in 32. This is the form many low-level tools (Wireshark filter expressions, BPF programs, eBPF maps) want.
Dotted hex (IPv4 only)
Each octet as a two-digit hex number, dot-separated: 0xC0.0x00.0x02.0x01 for 192.0.2.1. Some legacy networking tools accept this form; modern tools usually don't. Useful for manually constructing packet-level test data.
Binary
The raw bit pattern. We render with dots every 8 bits for v4 and every 16 bits for v6 to keep it readable. The binary form is the clearest illustration of subnet prefix length — when you compare 192.0.2.0/24 in binary, you can literally see which bits are network and which are host.
Octal (IPv4 only)
32-bit value rendered in base 8 with a leading zero (the traditional way to mark octal). Rarely useful in 2026, but some legacy Unix tools (older inet_addr implementations) actually parse it.
A gotcha worth knowing about
Some C and Java code treats IPv4 addresses as signed integers. The value 0xFFFFFFFF represents 255.255.255.255 as unsigned (4,294,967,295), but as signed two's-complement it reads as −1. This shows up in error messages and logs from time to time. PostgreSQL's inet column handles this correctly; raw integer columns require you to be explicit about signedness.
Adjacent tools
- IPv4 to IPv6 converter — mapped, hex-group, and 6to4 prefix forms.
- CIDR / subnet calculator — work with ranges.
- IPv6 toolkit — expand, compress, generate ip6.arpa reverse-DNS form.
- IP extractor — pull all IPs out of pasted text.
