What Base64 is and what it isn't
Base64 is a way to encode arbitrary bytes — including binary data like images or PDFs — using only 64 printable ASCII characters. It is defined in RFC 4648. Base64 is an encoding, not encryption: there is no key and anyone can decode the result. Its purpose is to transport binary data through systems (email headers, URL parameters, JSON values) that only safely handle text.
How the encoding works
Base64 takes input three bytes at a time (24 bits) and splits it into four groups of 6 bits. Each 6-bit group becomes one of 64 characters: A–Z, a–z, 0–9, +, /. If the input length is not a multiple of three, the output is padded with = signs so the length is always a multiple of four.
The encoded output is always 33% larger than the input — every 3 input bytes produce 4 output characters.
A worked example
Encoding the three ASCII bytes for "Man":
M= 77 =01001101a= 97 =01100001n= 110 =01101110- Concatenated:
010011010110000101101110 - Split into 6-bit groups:
010011 010110 000101 101110 - Values: 19, 22, 5, 46
- Mapped to alphabet:
TWFu
So "Man" encoded is "TWFu". Three bytes in, four characters out, no padding needed.
Standard, URL-safe, and other variants
| Variant | Alphabet | Padding | Use case |
|---|---|---|---|
| Standard (RFC 4648 §4) | A–Z a–z 0–9 + / | Required | MIME, general data transport |
| URL-safe (RFC 4648 §5) | A–Z a–z 0–9 - _ | Optional | URLs, file names, JWT |
| Base64url (no pad) | A–Z a–z 0–9 - _ | Stripped | JWT, JSON Web Signatures |
| Base32 | A–Z 2–7 | Required | Human-readable strings, OTP secrets |
| Base58 | Custom 58-char | None | Bitcoin addresses, IPFS |
The two characters that change between variants — + vs - and / vs _ — are chosen so that the URL-safe alphabet survives URL encoding without escaping.
When to use Base64
- Embedding images in CSS or HTML via
data:URIs to avoid an extra HTTP request. - Storing binary blobs in JSON (which natively has no binary type).
- Email attachments — MIME wraps every binary attachment in Base64.
- JWT tokens use Base64url for headers, payloads, and signatures.
- HTTP Basic Auth encodes
username:passwordas Base64. - Cryptographic key fingerprints (e.g. SSH key files contain Base64-encoded blobs).
When NOT to use Base64
- For secrets in URLs. Base64 looks scrambled but is fully reversible — anyone can decode an exposed token.
- For very large files in JSON. 33% size overhead plus the JSON-string escape overhead make it inefficient compared to a separate binary endpoint.
- Inside other Base64. Nested encoding makes debugging painful and doubles the size overhead.
- As password hashing. A Base64-encoded SHA-256 is still just SHA-256 — use a slow KDF like Argon2id or bcrypt for passwords.
Size and performance
The 4:3 expansion ratio is a hard limit — every Base64 string is exactly ceil(input_bytes / 3) × 4 characters long. With line breaks every 76 characters (MIME convention) the overhead climbs to about 37%. For very small inputs (under 4 KB), data-URI embedding saves an HTTP round-trip even with the overhead. For large assets, prefer a separate request and let the browser cache and compress it.