Base32hex is the extended-hex variant of Base32 from RFC 4648. It encodes the same 5-bits-per-character data, but with an alphabet that preserves sort order, which makes it the format behind DNSSEC NSEC3 records and similar order-sensitive keys.
Standard Base32 vs Base32hex — what actually differs
Both encodings pack exactly 5 bits into each ASCII character, producing strings that are 60% larger than their binary source but entirely safe for text contexts. The only difference is the alphabet:
| Position | Standard Base32 | Base32hex |
|---|---|---|
| 0–25 | A–Z | 0–9 (10 chars) then A–V (16 chars) |
| 26–31 | 2–7 | — |
| Padding | = | = |
Standard Base32 starts with letters, which means the encoded bytes 0x00 and
0xFF both encode to strings starting with A and 7 respectively — the
sort order of encoded strings does not match the sort order of the raw bytes.
Base32hex starts with digits 0 through 9 and then continues with A
through V, exactly mirroring how hexadecimal ordering works. This means if
you sort two Base32hex strings lexicographically, the result is the same as
sorting the underlying binary values numerically.
How it works
Encoding is identical to standard Base32 except for the symbol table. Bytes are read as a bit stream and chopped into 5-bit groups, each mapped through the extended-hex alphabet:
alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUV (index 0..31)
emit one character per 5 bits, zero-fill the last group
pad with '=' to a multiple of 8 characters (optional)
Because index 0 maps to 0 and the values climb monotonically through the
digits and then the letters, the lexical order of two encoded strings matches
the numeric order of the bytes they encode.
Why DNSSEC NSEC3 requires sort-order preservation
DNSSEC’s NSEC3 record type proves that a domain name does not exist by pointing from one hashed name to the next hashed name in sorted order, covering all names in between. DNS software must be able to walk these hashes in order to verify the proof. If the encoding did not preserve sort order, a DNS resolver would have to decode every hash before it could determine position — defeating the purpose of the compact encoding.
Base32hex was specified in RFC 4648 §7 precisely for this use case: an encoding that is case-insensitive, URL-safe, avoids punctuation that confuses zone files, and sorts correctly. NSEC3 records in every DNSSEC-signed zone you look up use this format.
When to use Base32hex vs. alternatives
| Need | Best choice | Reason |
|---|---|---|
| Sort-order preserved IDs | Base32hex | Only Base32 variant with this property |
| DNSSEC compatibility | Base32hex | Mandated by NSEC3 spec |
| General binary-to-text | Standard Base32 | Wider library support |
| Shortest output | Base64 | 33% overhead vs. 60% |
| Fully URL-safe, no padding | Base64url | Compact and URL-friendly |
Decoding notes
Any character outside 0–9 and A–V is invalid in Base32hex — specifically,
the letters W, X, Y, and Z are invalid here even though they are valid
in standard Base32. The decoder names the offending character so you can
spot mismatched-alphabet errors quickly.