Network traces, router dumps, and embedded logs often store IP addresses as hexadecimal. IPv4 fits in eight hex digits (32 bits). IPv6 uses longer hex groups. The hard part is rarely the conversion arithmetic—it is knowing which byte order the writer used.
Convert interactively with Hex to IP and IP to Hex.
IPv4: dotted decimal ↔ eight hex digits
192.168.1.1
C0 A8 01 01
192 168 1 1
→ C0A80101
Each octet becomes two hex digits. Many RFCs, Wireshark views, and teaching examples present bytes left-to-right in wire order, which yields C0A80101 for 192.168.1.1.
Endianness: the silent foot-gun
If software prints a uint32_t on a little-endian CPU with a naive %08x, you may see 0101A8C0 for the same address. Both strings are “valid hex.” Only one matches the address you expect.
- Wire / network order dumps: usually left-to-right as on the cable.
- Host integer printf: may look byte-swapped on little-endian machines.
- Fix: document the source. When unsure, convert both interpretations and compare to a known dotted IP from the same system.
IPv6 is still hex—just longer
2001:0db8:85a3:0000:0000:8a2e:0370:7334
IPv6 is 128 bits → 32 hex digits, commonly eight groups of four. :: compression is a textual shortcut; expand before parsing into raw bytes.
Implementation sketch (IPv4 wire order)
def hex_to_ipv4(h: str) -> str:
h = "".join(h.split())
if h.lower().startswith("0x"):
h = h[2:]
if len(h) != 8 or any(c not in "0123456789abcdefABCDEF" for c in h):
raise ValueError("IPv4 hex must be 8 hex digits")
return ".".join(str(int(h[i:i+2], 16)) for i in range(0, 8, 2))
def ipv4_to_hex(ip: str) -> str:
parts = [int(p) for p in ip.split(".")]
if len(parts) != 4 or any(p < 0 or p > 255 for p in parts):
raise ValueError("invalid IPv4")
return "".join(f"{p:02X}" for p in parts)
assert hex_to_ipv4("C0A80101") == "192.168.1.1"
assert ipv4_to_hex("192.168.1.1") == "C0A80101"
Validation checklist
- Strip spaces and
0x. - IPv4 → length 8; IPv6 → length 32 after expansion.
- Hex digits only.
- Confirm byte order against the producing tool.
- Round-trip to dotted form when you have a ground-truth address.
Ports and neighboring fields
Hex dumps rarely contain “just an IP.” A TCP header places addresses next to ports and sequence numbers. If you slice eight digits from the wrong offset, you get a plausible-looking address that belongs to nobody on your network.
- Prefer a parser that understands the protocol.
- When extracting manually, mark offsets on paper or in comments.
- Cross-check with Wireshark’s decoded view when available.
FAQ
Why does my hex look right but ping fails?
Often endianness—or you converted a port, VLAN tag, or neighboring field by accident.
Are MAC addresses the same idea?
Similar (hex bytes), different length and rules. Do not run MAC strings through an IPv4 converter.
Does IPv4-mapped IPv6 change the hex length?
Yes. Forms like ::ffff:192.168.1.1 expand to a full 128-bit IPv6 address; do not treat the dotted tail as a standalone 8-digit IPv4 hex field without reading the surrounding zeros.
Related: odd-length and whitespace pitfalls · file magic numbers · Hex Calculator · overview hex encoding.