Skip to content
HandfulTools

Base64 explained: what it is, when to use it and when not to

How Base64 turns binary data into text, why it makes files 33% larger, the difference with Base64URL, and why it is not encryption.

· 5 min read

Base64 rewrites arbitrary binary data using only 64 characters that survive any text channel. It is a transport format, not a security measure: anyone can reverse it in a second, and the result is about a third larger than what you started with. It shows up in email attachments, data URLs in CSS, JSON APIs, JSON Web Tokens and HTTP Basic authentication.

The quickest route here: paste your text or drop a file into the Base64 encoder, or go the other way with the Base64 decoder. Both run in the browser, so nothing is sent anywhere.

How it works

Many protocols were designed to carry text, not arbitrary bytes. A byte can hold any of 256 values, and some of them — null bytes, control characters, anything above 127 — get mangled, truncated or reinterpreted along the way.

Base64 solves this by ignoring byte boundaries and regrouping the bits. Take 3 bytes — 24 bits — and cut them into four groups of 6 bits. Six bits hold 64 values, and each value maps to one character of the alphabet A–Z, a–z, 0–9, + and /. Three bytes in, four characters out, every time.

When the input length is not a multiple of 3, the last group is padded with = so the output length stays a multiple of 4:

Input Bytes Output Padding
Man 3 TWFu none
Ma 2 TWE= one =
M 1 TQ== two =
Hello, world! 13 SGVsbG8sIHdvcmxkIQ== two =

The size increase, exactly

Four characters for every three bytes is a ratio of 4 ÷ 3 = 1.3333, so Base64 output is 33.33% larger than the input. That figure is exact only when the input length is a multiple of 3; padding makes short strings worse. Hello, world! is 13 bytes and encodes to 20 characters, 54% more.

Input Encoded Increase
2 KiB (2,048 bytes) 2,732 characters 33.40%
40 KiB (40,960 bytes) 54,616 characters 33.34%
1 MiB (1,048,576 bytes) 1,398,104 characters 33.33%

Email adds a little more. MIME wraps Base64 at 76 characters per line, and each line break costs 2 more bytes, another 2.63%. A 1 MiB attachment therefore travels as roughly 1,434,898 bytes — about 37% larger than the file on disk. That is why a 20 MB mailbox limit stops attachments well under 20 MB.

If you need to convert those units, the Data storage converter handles bytes, KiB, KB, MiB and MB.

Text has to become bytes first

Base64 encodes bytes, so text must first be turned into bytes — in practice with UTF-8. café is four characters but five bytes in UTF-8, because é takes two, and it encodes to Y2Fmw6k=.

This is exactly where the browser's built-in btoa() fails: it only accepts code points up to 255, so accented letters and emoji throw an error or, worse, get silently mangled if you work around it wrongly. The encoder here converts to UTF-8 first, which is what you almost always want. When you decode, you have to reverse both steps — bytes back from Base64, then text back from UTF-8.

Base64URL

Standard Base64 uses + and /, which both have special meanings in URLs, and =, which is the query-string separator. Base64URL is the same algorithm with two substitutions — + becomes -, / becomes _ — and the padding usually dropped. The byte sequence that gives +//+ in standard Base64 gives -__- in Base64URL.

JSON Web Tokens use Base64URL for all three of their parts. That is why the header {"alg":"HS256","typ":"JWT"} always appears as eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9, and why the JWT decoder can show you the contents of any token without a key.

Base64URL is not the same as percent-encoding. If you need to make an arbitrary string safe inside a URL or a form body, that is the job of the URL encoder.

Data URLs

A data URL embeds a file directly in markup or CSS: data:image/png;base64,iVBORw0KGgo…. The browser decodes it with no extra request. The trade-offs are real:

  • The payload is 33% larger, and it cannot be cached separately from the document that contains it.
  • Repeating the same icon in three stylesheets means shipping it three times.
  • Content Security Policy rules often block data: sources, especially for scripts and frames.

The usual rule of thumb is to inline only very small assets — a handful of kilobytes — and to serve anything bigger as a normal file. SVG is often a better answer than a Base64 PNG, since it can be written directly into HTML without any encoding.

Base64 is not encryption

Decoding needs no key, no password and no effort. Base64 hides nothing.

HTTP Basic authentication sends username:password as Base64 in a header, which is not protection at all — it is exactly why Basic auth must only be used over HTTPS. The payload of a JWT is signed, not encrypted, so anyone holding the token can read the claims inside it.

If you actually need one of the properties people hope Base64 provides:

What you want What to use instead
Confidentiality Encryption (TLS in transit, AES or similar at rest)
Proof a file is unchanged A hash such as SHA-256 — see the Hash generator and the guide How to verify a download with a checksum
A safe value in a URL Percent-encoding, or Base64URL
A smaller payload Compression, before encoding if you must encode

Questions people ask

Does Base64 compress anything? No, the opposite. If size matters, compress first and encode the compressed bytes.

Why does my Base64 string end in = and another one does not? Padding depends only on the input length modulo 3. Base64URL often omits it entirely, and decoders generally cope.

Can I put Base64 in JSON? Yes — that is one of its main uses, since JSON strings cannot hold arbitrary bytes. Validate the result with the guide How to format, validate and fix JSON.

My decoded file is corrupted. Usually one of three things: the string was truncated in transit, it was Base64URL decoded as standard Base64, or whitespace and line breaks were not stripped first.

Next steps

Tools used in this guide

← All guides