Base64 vs Hex Encoding: Size, Speed and Use Cases

Updated

Base64 is more compact; hex is easier to read. Hex (Base16) writes every byte as two characters, so the text is twice the size of the data, while Base64 writes every three bytes as four characters, about 33% larger. Choose hex when people need to read or compare bytes, such as hashes and colors, and Base64 when size matters, such as files, tokens and data URIs.

Both are defined in RFC 4648, both are lossless, and neither provides any secrecy. They differ in alphabet, size and how well they fit into URLs, file names and sorted lists.

Base64 vs hex: size of a 32-byte SHA-256 digest Bar chart. The 32 raw bytes of a SHA-256 digest take 64 characters in hex (plus 100 percent), 56 in Base32 with padding (plus 75 percent for this length), and 44 in Base64 with padding (plus 37.5 percent). Hex is easiest to read; Base64 is most compact. Same 32 bytes, three encodings SHA-256 digest of "hello" · characters needed Raw bytes 32 Hex (Base16) 64 (+100%) Base32 56 (+75%) Base64 44 (+37.5%) hex 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 base64 LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ= Hex: readable, case-insensitive, sortable. Base64: compact; use base64url in URLs.
Size of 32 bytes in hex (64 characters), Base64 (44) and Base32 (56)

How each encoding works

Hex (Base16) splits each byte into two 4-bit halves and writes each half as one of 16 symbols, 0–9 and A–F (lowercase is common too). The letter H is byte 0x48, written 48.

Base64 takes 24 bits (three bytes) at a time and splits them into four 6-bit groups, each written as one of 64 symbols: A–Z, a–z, 0–9, + and /. The output is padded with = to a multiple of four characters. The URL-safe variant, base64url, uses - and _ instead of + and /.

Input Hex Base64
Hello (5 bytes) 48656c6c6f (10 chars) SGVsbG8= (8 chars)
foobar (6 bytes) 666f6f626172 (12 chars) Zm9vYmFy (8 chars)
SHA-256 of hello (32 bytes) 2cf24dba…938b9824 (64 chars) LPJNul+wow4m…pOLmCQ= (44 chars)

The foobar row matches the test vectors in RFC 4648, section 10.

Side-by-side comparison

Hex (Base16) Base64 Base64url
Characters per byte 2 1.33 1.33
Size increase +100% +33% (plus padding) +33% (padding often dropped)
Alphabet 0–9 a–f A–Z a–z 0–9 + / and = A–Z a–z 0–9 - _
Case-sensitive No Yes Yes
Safe in URLs without escaping Yes No (+, /, =) Yes
Safe in file names Yes No (/) Yes
Easy to read byte by byte Yes No No
Sorts in the same order as the bytes Yes (same case, same length) No No

Two of these rows are easy to overlook:

  • Case. 2CF24D and 2cf24d are the same hex value, so case-insensitive systems (some file systems, email addresses, DNS) do not damage it. Base64 depends on case; a and A are different values.
  • Sorting. Because 0–9 come before a–f in ASCII, hex strings of the same length and case sort in the same order as the bytes they represent. The Base64 alphabet starts with uppercase letters and ends with + and /, so its sort order does not follow the data.

About speed

Both encodings are simple table lookups and are fast in every mainstream language; for most applications the cost of moving the data dominates. The size difference has a more visible effect than the encoding work: hex output is 50% longer than Base64 for the same bytes, so it takes more space in storage, logs and network traffic. If throughput truly matters, measure with your own runtime and data rather than relying on general claims.

Where each one is the convention

Hex is usual for:

  • Hash digests printed by command-line tools such as sha256sum and md5sum
  • Colors in CSS (#0b5ed7), MAC addresses and UUIDs
  • Byte dumps in debuggers and network tools
  • Percent-encoding in URLs, which writes each byte as % plus two hex digits

Base64 is usual for:

  • Email attachments (MIME)
  • Data URIs such as data:image/png;base64,…
  • JSON Web Tokens, which use base64url for each part (RFC 7519)
  • Subresource Integrity hashes in HTML, where MDN documents the format as an algorithm prefix followed by a Base64-encoded digest, for example sha384-…
  • Binary values in JSON and XML APIs

Base32 (also in RFC 4648) is a middle ground: 8 characters for every 5 bytes (+60%), using uppercase letters and the digits 2–7 only, so it survives case-insensitive systems better than Base64. foobar in Base32 is MZXW6YTBOI======.

Converting between hex and Base64

Always decode to bytes first; never Base64-encode the hex text itself.

// Node.js
Buffer.from("48656c6c6f", "hex").toString("base64");   // "SGVsbG8="
Buffer.from("SGVsbG8=", "base64").toString("hex");      // "48656c6c6f"
import base64
base64.b64encode(bytes.fromhex("48656c6c6f"))   # b'SGVsbG8='
base64.b64decode("SGVsbG8=").hex()               # '48656c6c6f'
# SHA-256 digest as Base64 (the format used by Subresource Integrity)
printf 'hello' | openssl dgst -sha256 -binary | base64
# LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=

A common mistake is comparing a digest from one tool in hex with a digest from another in Base64 and concluding they differ. 2cf24dba…9824 and LPJNul+wow4m…mCQ= are the same 32 bytes.

Pitfalls when switching between them

  • Treating hex text as bytes. "48656c6c6f" is 10 ASCII characters. Base64-encoding that text gives NDg2NTZjNmM2Zg==, not SGVsbG8=. Decode the hex first.
  • Mixing alphabets. Standard Base64 and base64url differ in two characters. A decoder that expects one may reject or mis-read the other, so normalize -/_ to +// (or the reverse) before decoding.
  • Missing or extra padding. Base64url values often drop =. Some decoders require padding; add = until the length is a multiple of four.
  • Line breaks. MIME tools wrap Base64 at 76 characters. Strip whitespace before decoding or comparing.
  • Case changes. Uppercasing a Base64 string corrupts it. Uppercasing hex is harmless, but compare digests case-insensitively.
  • Unescaped + in URLs. A Base64 value placed in a query string without encoding loses its + signs, which form-style parsers read as spaces. Use base64url or percent-encode the value.

How to choose

  1. Will people read, type or compare it? Use hex.
  2. Is size important, or is it a whole file? Use Base64.
  3. Does it go into a URL, cookie or file name? Use base64url or hex, not standard Base64.
  4. Must it survive case-insensitive systems? Use hex or Base32.
  5. Does a standard already decide? Follow it: JWT uses base64url, SRI uses Base64, checksum files use hex.

Try both

The universal encoder decoder converts text to and from Base64 and hex (string to hex and back), so you can compare the two outputs for the same input. For files and images, the image to Base64 tool shows the encoded size. To see why Base64 adds a third, read why Base64 makes data about 33% larger; for the digests themselves, see MD5 vs SHA-256 for file checksums; and for base64url in practice, see how to decode a JWT without the secret.

Frequently asked questions

Which is smaller, Base64 or hex?

Base64. Hex writes each byte as two characters, doubling the size. Base64 writes three bytes as four characters, about 33% larger than the data. A 32-byte SHA-256 digest is 64 characters in hex and 44 in Base64.

Can I convert a hex string to Base64 directly?

Yes, but go through bytes: decode the hex to bytes, then Base64-encode those bytes. Base64-encoding the hex text itself gives a different and much longer result.

Is hex or Base64 more secure?

Neither. Both are reversible encodings with no key. They only change how bytes are written as text; any protection has to come from encryption or signatures.

Encode or decode text now with the free Universal Encoder Decoder: Base64, URL, HTML entities, hex, binary and hashes.

Open the encoder

Sources