All articles

Base32: how it differs from Base64 and when it is more convenient

Base32 exists for one reason: sometimes a human, not a program, has to read, type, or say the encoded string out loud. A 32-character alphabet (A–Z, 2–7) makes that far less error-prone than Base64's 64 characters ever could.

Set up 2FA manually and you've already typed Base32

When an authenticator app (Google Authenticator, Authy, 1Password) can't scan a QR code, it asks for a "setup key" instead — that string is Base32, not Base64. The otpauth:// URI that the QR code actually encodes carries a secret= parameter, and the spec requires it to be Base32 specifically so a person can type it in by hand without hitting an ambiguous character.

The alphabet is designed to survive a phone call

Base32 drops 0, 1, 8, 9 and the letters O, I, L — the exact set that gets misheard or misread when someone reads a code aloud or squints at a low-resolution screen. Base64's alphabet includes both cases of every letter plus + and /, which is efficient for machines but a minefield for dictation.

It shows up anywhere case doesn't survive the trip

  • Tor's .onion v3 addresses — the 56-character subdomain is a Base32 encoding of an Ed25519 public key.
  • DNS labels and subdomains, which are case-insensitive by spec, so a Base64 string with mixed-case meaning would silently break there.
  • Filenames on case-insensitive filesystems, where two Base64 strings differing only in case would otherwise collide.

The trade-off: length

Fewer symbols per character means more characters overall — roughly 60% longer than the equivalent Base64. For a 20-byte TOTP secret that's a handful of extra characters; nobody reaches for Base32 to shrink a multi-megabyte file.

Base32 vs. Base32hex — not interchangeable

RFC 4648 also defines Base32hex, which swaps the alphabet to 0–9A–V so that sorting encoded strings lexicographically gives the same order as sorting the original bytes — a property some databases and filesystems rely on. A string encoded as standard Base32 won't decode correctly as Base32hex, so it's worth checking which variant a given API or spec actually expects before assuming.

Try the tool