Base64 is an encoding scheme that converts binary data into a string of 64 printable ASCII characters. It's not encryption — it doesn't protect data. It just makes binary data safe to transport over text-based systems.
Why Base64 Exists
Many protocols (email, HTTP headers, URLs) were designed for ASCII text. Binary data — images, PDFs, executable files — contains bytes that can corrupt these protocols. Base64 solves this by representing any binary data using only letters, numbers, +, /, and =.
Binary: 01001000 01100101 01101100 01101100 01101111
Text: "Hello"
Base64 encoded: "SGVsbG8="How It Works
Base64 takes 3 bytes (24 bits) and encodes them as 4 characters (6 bits each). This is why Base64 output is always 4/3 the size of the original — a 300-byte file becomes 400 characters of Base64.
The = padding at the end appears when the input isn't divisible by 3.
Common Use Cases
- Data URIs — embed images directly in HTML/CSS:
<img src="data:image/png;base64,iVBOR..."> - JWT tokens — the header and payload are Base64url-encoded (URL-safe variant)
- Email attachments — MIME standard requires attachments to be Base64-encoded
- API payloads — sending binary files (PDFs, images) in JSON APIs
- Basic Auth — HTTP Basic Authentication encodes
username:passwordin Base64 - Cryptographic keys — PEM format uses Base64 to represent key bytes
Base64 vs URL-safe Base64
Standard Base64: uses + and / which have meaning in URLs
URL-safe Base64: replaces + with - and / with _ (safe in URLs)
Standard: "SGVsbG8+Wg=="
URL-safe: "SGVsbG8-Wg" (also removes padding =)
# JavaScript
btoa("Hello") // Standard Base64
btoa("Hello").replace(/+/g, '-').replace(///g, '_').replace(/=/g, '') // URL-safeBase64 Is NOT Encryption
This is the most important thing to understand. Base64 encoding is trivially reversible by anyone. Never use it to "protect" sensitive data — anyone who sees the encoded string can decode it instantly. Use encryption (AES) for protecting data, not Base64.
// This is NOT secure
const "secret" = btoa("password123") // "cGFzc3dvcmQxMjM="
atob("cGFzc3dvcmQxMjM=") // "password123" — trivial to reverse