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.
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.
2CF24Dand2cf24dare the same hex value, so case-insensitive systems (some file systems, email addresses, DNS) do not damage it. Base64 depends on case;aandAare different values. - Sorting. Because
0–9come beforea–fin 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
sha256sumandmd5sum - 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 givesNDg2NTZjNmM2Zg==, notSGVsbG8=. 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
- Will people read, type or compare it? Use hex.
- Is size important, or is it a whole file? Use Base64.
- Does it go into a URL, cookie or file name? Use base64url or hex, not standard Base64.
- Must it survive case-insensitive systems? Use hex or Base32.
- 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