Guide

Hex vs. Base64 encoding explained

Binary data—compiled bytecode, image files, encrypted ciphertext, and cryptographic hash outputs—cannot safely travel across text-only protocols like HTTP, JSON payloads, or email bodies without corrupting raw bytes. Binary-to-text encodings solve this by mapping raw bytes into restricted subsets of human-readable ASCII characters. The two most ubiquitous encodings in software engineering are Base16 (Hexadecimal) and Base64.

While both formats represent the exact same underlying binary data, they make fundamentally different trade-offs between character efficiency, human readability, byte alignment, and URL safety. Choosing the wrong encoding can double your network payload size or cause silent character corruption when passing identifiers through web forms and query parameters.

Open the Hex Decoder

Use this when


  • Decoding cryptographic hash digests (SHA-256, MD5) and digital signatures
  • Inspecting raw byte streams, protocol headers, and network packet dumps
  • Deciding between Hex and Base64 for serializing binary data in JSON API payloads
  • Debugging corrupted character encodings, UTF-8 byte-order marks, and zero-width spaces
  • Passing binary identifiers or encryption initialization vectors (IVs) through URL parameters

The math of representation: 100% vs. 33% overhead


Hexadecimal (Base16) uses a 16-character alphabet (0-9 and a-f). Because 16 is 2^4, each hexadecimal character represents exactly 4 bits, commonly referred to as a nibble. Since a standard byte consists of 8 bits, every single input byte requires exactly two hexadecimal characters to represent. This creates a fixed 100% storage overhead: a 100 KB binary file will always expand to exactly 200 KB of hexadecimal text.

Base64 uses a 64-character alphabet (A-Z, a-z, 0-9, plus, and slash). Because 64 is 2^6, each Base64 character represents 6 bits of data. Base64 processes data in 3-byte groups (24 bits), which divide evenly into four 6-bit characters. This results in only a 33.3% size expansion: a 100 KB binary file expands to approximately 133 KB in Base64.

When transferring data over the network—such as embedding inline thumbnail images in CSS, sending attachments via SMTP MIME, or passing binary payloads in JSON API responses—Base64 is substantially more efficient than Hexadecimal, saving 33% of bandwidth compared to a hex string.

Encoding overhead and character density comparison
Encoding SchemeAlphabet SizeBits / CharPayload Expansion OverheadPrimary Use Case
Base16 (Hexadecimal)16 chars (0-9, a-f)4 bits+100% (2x original bytes)Hashes, UUIDs, byte debugging, MAC addresses
Base64 (Standard)64 chars (A-Z, a-z, 0-9, +, /)6 bits+33.3% (4 chars per 3 bytes)API payloads, data URIs, email attachments
Base64url (Safe)64 chars (A-Z, a-z, 0-9, -, _)6 bits+33.3% (no padding)JWT tokens, URL query parameters

Byte boundaries and human inspectability


Hexadecimal’s greatest engineering advantage is its clean, 1:1 byte alignment. Exactly two hex characters represent one byte. The first byte of a string or file corresponds directly to the first two characters of the hex string, the second byte corresponds to characters three and four, and so on.

Base64, by contrast, straddles byte boundaries. Three 8-bit bytes are distributed unevenly across four 6-bit characters. The second Base64 character contains the bottom 2 bits of the first byte and the top 4 bits of the second byte. As a result, you cannot inspect, slice, or edit individual byte offsets in a Base64 string without decoding the entire 24-bit block.

This 1:1 mapping makes Hexadecimal the universal standard for debugging: inspecting UTF-8 byte signatures, analyzing memory dumps, diagnosing byte order marks (EF BB BF), and reading magic numbers in binary file headers (such as 89 50 4E 47 for PNG or FF D8 FF for JPEG).

Raw ASCII Text : Hello
Hex (Base16)   : 48 65 6c 6c 6f       (5 distinct byte pairs)
Base64         : SGVsbG8=             (4 characters + 1 char + 1 padding)
Comparing 1:1 byte alignment in Hex vs 6-bit straddling in Base64 for "Hello"

Cryptographic hashes and identifiers: Why security prefers Hex


A common question among developers is why SHA-256 digests, MD5 checksums, Git commit hashes, and UUIDs default to Hexadecimal formatting instead of the more compact Base64.

A SHA-256 hash produces 256 bits (32 bytes). In Hexadecimal, it renders as a uniform, fixed 64-character string composed exclusively of alphanumeric characters (0-9, a-f). It contains no punctuation marks, spaces, or symbols.

This makes Hex hashes completely safe in shell scripts, command-line arguments, file paths, and database query parameters without requiring quotes, URL-escaping, or regex sanitization. While a Base64 SHA-256 digest is shorter (44 characters), its use of punctuation characters creates unnecessary friction in CLI tools and URL query strings.

URL safety and character collision risks


Standard Base64 uses the plus sign (+) and forward slash (/) as its 62nd and 63rd characters. In standard URL and URI syntax, both characters carry reserved structural meaning: a plus sign represents a space in application/x-www-form-urlencoded query strings, while a slash serves as a hierarchical path separator.

If a standard Base64 token is appended to a URL without percent-encoding, web servers and HTTP proxies will often decode the plus sign into a space, permanently corrupting the binary data. To fix this, RFC 4648 defined Base64url, which replaces plus with hyphen (-) and slash with underscore (_).

Hexadecimal, on the other hand, is inherently URL-safe out of the box. The digits 0-9 and letters a-f are all unreserved ASCII characters that can travel through URLs, cookie headers, and web forms without escaping.

Trailing padding: The role of equals signs in Base64


Because Base64 operates in 24-bit (3-byte) blocks, it must handle input byte lengths that do not divide evenly by 3. This is where trailing equals signs (=) come from.

If an input has one trailing byte remaining (8 bits), Base64 adds 4 zero bits to form two 6-bit characters, then appends two equals signs (==) to record that two padding bytes were added. If an input has two trailing bytes remaining (16 bits), Base64 adds 2 zero bits to form three 6-bit characters, then appends one equals sign (=).

Hexadecimal never requires padding characters. Because every single byte translates cleanly into two characters, the only structural validation rule in Hex is that the total character count must be even. An odd number of hex characters is a definitive indicator of a truncated or corrupt stream.

Common problems


Each of these is something that actually happens, with the cause rather than a generic suggestion to check your input.

Hex decoding failed with an odd digit count error

Cause
Hexadecimal requires exactly two characters per byte. An odd total character count indicates a missing digit or truncated input.
Fix
Check your source string for missing leading zeros (such as 0a written as a) or incomplete byte streams before decoding.

Base64 string was corrupted when passed in a URL query parameter

Cause
Standard Base64 contains plus characters (+), which HTTP servers automatically decode into spaces before your application reads them.
Fix
Use the URL-safe Base64url variant (substituting - for + and _ for /) or percent-encode the string before appending it to the query.

Decoded text contains question marks or replacement characters

Cause
The byte stream was decoded using the wrong character encoding (such as ISO-8859-1 instead of UTF-8) or contained raw non-text binary data.
Fix
Verify that the input bytes represent valid UTF-8 text, or inspect the raw hex values to confirm character byte boundaries.

Hex comparison between two systems failed despite identical byte values

Cause
One system emitted uppercase hex (1A2B) while the other emitted lowercase (1a2b) or included 0x prefixes or spaces.
Fix
Strip 0x prefixes, colons, and spaces, and normalize strings to lowercase before running equality comparisons.

Questions


Which encoding produces smaller files, Hex or Base64?
Base64 produces significantly smaller files. Base64 increases data size by 33%, while Hexadecimal increases data size by 100% (doubling the raw byte count).
Why does Git use Hex for commit hashes instead of Base64?
Hexadecimal strings contain only letters and numbers (no + or / symbols), making them completely safe in terminal commands, file paths, URLs, and Git references without escaping.
Is Hexadecimal case-sensitive?
No. The characters a-f represent the decimal values 10 through 15 regardless of whether they are uppercase or lowercase. However, applications should normalize to lowercase for string matching.
Can any text or file be converted to both Hex and Base64?
Yes. Both formats can represent any arbitrary sequence of bytes with 100% fidelity. They are lossless, deterministic representations of raw binary data.