Base64 vs hex: representing bytes
Published: 2026-09-05
How Base64 and hexadecimal both encode the same bytes, why hex expands ~2× and Base64 ~33%, when each format shows up in APIs and hashes, and how to compare them locally in the browser.
Base64 and hex (hexadecimal) are two ways to write the same sequence of bytes as text. Neither encrypts nor compresses; both are reversible encodings so binary can travel in JSON, logs, emails, and copy-paste fields that only accept printable characters. Choosing the wrong one usually means a failed checksum compare or a “invalid Base64” error—not a mystery crypto bug.
This guide compares density, alphabets, and real-world conventions, then points you at a local tool that shows both encodings (and common hashes) side by side.
Same bytes, different text
Start with three UTF-8 bytes for the ASCII string Hi!:
| Byte (decimal) | Hex pair | Meaning |
|---|---|---|
| 72 | 48 |
H |
| 105 | 69 |
i |
| 33 | 21 |
! |
- Hex:
486921(six characters for three bytes) - Base64:
SGkh(four characters for three bytes)
Decode either string and you get the identical byte array. The formats disagree only on how densely and with which alphabet those bytes are spelled.
For a deeper UTF-8 / hex dump walkthrough, see Hex encoding: UTF-8 bytes explained.
Density: why hex is longer and Base64 is “only” ~33% bigger
| Format | Rule of thumb | Expansion vs raw bytes |
|---|---|---|
| Hex | 2 ASCII chars per byte | ~100% larger |
| Base64 | 4 ASCII chars per 3 bytes | ~33% larger |
Hex maps each nibble (4 bits) to one digit 0–9 / A–F. Base64 packs 6 bits into one character from a 64-symbol alphabet, so three bytes (24 bits) become four characters.
Padding matters for Base64: lengths that are not a multiple of three end with = or == so decoders know how many leftover bits to ignore. Hex needs an even digit count; odd length usually means a truncated dump.
Alphabets and where they fit
| Hex | Base64 | |
|---|---|---|
| Characters | 0–9, a–f / A–F |
A–Z, a–z, 0–9, +, /, padding = |
| Case | Often case-insensitive when comparing | Case-sensitive |
| URL-safe? | Fine in query values if you still percent-encode when required | Standard + / / need care in URLs; Base64URL uses - / _ instead |
| Human scanning | Easy to spot magic numbers (89 50 4E 47 PNG) |
Harder to eyeball; denser for wire transfer |
Hex wins for debugging and teaching. Base64 wins when you need to shove binary into a text protocol without doubling the size.
Where each shows up
Hashes and checksums
Cryptographic digests are fixed-length byte arrays. Documentation and CLIs almost always print them as lowercase or uppercase hex:
SHA-256("") → e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
The same digest as Base64 is shorter but less common in checksum files and shasum-style output. When you compare a published hash to a tool result, match both the algorithm and the encoding (hex vs Base64), and treat hex compare as case-insensitive.
APIs, JWT, and data URLs
- JSON APIs often Base64-encode binary fields (keys, ciphertext, file blobs) so the payload stays valid UTF-8 JSON.
- JWT segments use Base64URL (no padding in many libraries)—related to Base64, not hex. See Reading a JWT without trusting the server.
- Data URLs embed image bytes as Base64 after a MIME type; see Embedding images as Base64 data URLs.
Logs and hex dumps
Packet captures, firmware, and xxd-style dumps prefer hex with spaces or offsets. You rarely see a full Base64 line in a binary protocol dump unless the protocol itself uses Base64 on the wire.
Encoding text: UTF-8 first
“Encode this string to Base64/hex” almost always means:
- Encode the Unicode string as UTF-8 bytes.
- Format those bytes as Base64 or hex.
So é becomes UTF-8 bytes c3 a9, hex c3a9, Base64 w6k=—not a single Latin-1 byte e9. Mixing charset assumptions is a classic “works on my machine” failure when one side uses UTF-8 and another uses a legacy single-byte encoding.
Common pitfalls
- Comparing hex to Base64: They will never string-equal for the same bytes. Decode both to bytes or re-encode one side before comparing.
- Assuming encoding hides secrets: Both are reversible. Encoding is not hashing, and hashing is not encryption.
- URL and HTML layers: Putting Base64 in a query string may still need percent-encoding; putting raw text in HTML still needs entity escaping. Hex dumps are not HTML
&#x…;entities (those are Unicode code points). - Whitespace and prefixes: Hex dumps may include spaces,
0x, or newlines. Base64 may be wrapped at 76 characters (MIME). Strip formatting before decode, or use a tool that tolerates it. - Wrong Base64 dialect: Standard vs Base64URL (
+//vs-/_, padding rules) breaks interoperable decode if you mix them.
When a local Base64 + hash tool helps
Typical tasks:
- Paste a string and see Base64 and UTF-8 hex update together so you can confirm they describe the same bytes.
- Compute SHA-256 / SHA-512 / SHA-1 / MD5 of text (and a small file checksum) and compare against a published hex digest.
- Sanity-check an API field: is this value Base64 of UTF-8 text, or hex of a hash?
- Keep tokens, secrets, and file checksums in the browser when you do not want to upload them.
Encoding and hashing here are pure client-side work—safe for sensitive strings when nothing leaves the tab. For why that matters, see Why “local only” matters for developer tools.
Try it locally in your browser
Use the Multi-Hash & Base64 Factory to:
- Type or paste text and get Base64, hex (UTF-8), URL encoding, and HTML entities live.
- Compute SHA-256, SHA-512, SHA-1, and MD5 in the same view; Compare against an expected value (hex hashes are case-insensitive).
- Drop a file under 10 MB for a local SHA-256 checksum—processing stays in your browser.
For focused hex dumps with byte views and flexible decode, use the Hex Encoder & Decoder. For image data URLs specifically, use Image to Base64.
Related reading
- Hex encoding: UTF-8 bytes explained — characters vs UTF-8 bytes, spaced dumps, and hex vs percent-encoding.
- Embedding images as Base64 data URLs in CSS and HTML — MIME + Base64 embeds and the ~33% size tax.
- URL encoding vs form encoding — when byte values need
%HHinstead of a raw Base64 or hex string. - Why “local only” matters for developer tools — keeping payloads and checksums off someone else’s server.