Base64 Base64 Encoding Encoding Schemes Flagship
A binary-to-text encoding scheme that represents arbitrary bytes using 64 printable ASCII characters — not encryption, and not compression.
What it is
Base64 is a binary-to-text encoding scheme — it takes arbitrary binary data (images, files, encrypted blobs, anything) and represents it using only 64 printable ASCII characters (A-Z, a-z, 0-9, +, /), plus = for padding. It exists because many systems — email (historically), JSON, XML, URLs, older text-only transport protocols — can't safely carry raw binary bytes, but can reliably carry plain ASCII text. Base64 is the standard bridge between the two.
It's important to be precise about what Base64 is not: it is not encryption (anyone can decode it instantly, with zero secret key), and it is not compression (encoded output is always larger than the input, never smaller). It's purely a representation format — the same information, in a different, transport-safe shape.
You'll find this tool already built on this site at Base64 encode/decode — this page covers the underlying mechanics for when you need to reason about it directly.
Byte structure
Base64 works in groups of 3 input bytes → 4 output characters:
| Input | Output |
|---|---|
| 3 bytes (24 bits) | 4 Base64 characters (6 bits each = 24 bits) |
| 2 bytes (16 bits) | 3 characters + 1 = padding character |
| 1 byte (8 bits) | 2 characters + 2 == padding characters |
Each Base64 character represents exactly 6 bits, chosen from a 64-character alphabet (2^6 = 64) — hence the name. Since 3 bytes (24 bits) divides evenly into four 6-bit groups, that's the natural batching unit. When the input isn't a clean multiple of 3 bytes, = padding characters fill out the final group so decoders know exactly how many "real" bytes were in the last chunk.
This structure is also why Base64-encoded data is always roughly 33% larger than the original binary — 3 bytes become 4 characters, a fixed 4:3 expansion ratio regardless of content.
Why your data is broken (symptom → cause)
| Symptom | Likely cause |
|---|---|
| Decoded output is garbage or throws an error | Wrong Base64 variant (standard vs. URL-safe) — see below — or the input has been altered/truncated (e.g., whitespace stripped incorrectly, or line breaks mid-string not handled) |
| String works standalone but breaks inside a URL | Standard Base64 uses + and /, both of which have special meaning in URLs (+ means space, / is a path separator) — you need the URL-safe variant (- and _ instead) |
| "Invalid character" error on decode | Standard vs. URL-safe alphabet mismatch, or the string was accidentally URL-decoded/re-encoded somewhere in transit, corrupting + characters into spaces |
Missing or extra = padding causes decode failure |
Some systems strip trailing = padding (common in URL-safe/JWT contexts) but the decoder being used still expects it — most modern decoders can be configured to handle both |
| File corrupted after Base64 round-trip through an email client | Legacy email systems sometimes insert line breaks at fixed intervals (part of the original MIME spec) — a decoder not expecting embedded newlines can fail or produce corrupted output |
Compatibility & gotchas
- Standard vs. URL-safe alphabets. Standard Base64 uses
+and/as its last two characters; URL-safe Base64 (RFC 4648 §5) replaces them with-and_specifically so the output can appear in URLs and filenames without needing further escaping. JWTs (JSON Web Tokens) use URL-safe Base64 without padding — a common source of "why doesn't this decode" confusion when using a standard decoder on JWT segments. - It is not encryption. This bears repeating because it's a genuinely common misunderstanding: Base64-encoded data is fully and instantly reversible by anyone, with no secret required. Never use Base64 alone to "hide" sensitive data — if you see credentials or tokens that are "just" Base64-encoded, treat them as plaintext for security purposes.
- It's not compression, and it can't be. The ~33% size increase is unavoidable given the 6-bits-per-character design; if you're Base64-encoding data for storage/transmission efficiency, you're doing the opposite of what you likely intend — compress first, then Base64-encode the compressed bytes if a text-safe transport is genuinely needed.
- Embedding images in HTML/CSS via
data:URIs uses Base64 — but the 33% size penalty plus loss of separate HTTP caching (the image becomes part of the HTML/CSS payload, cached or invalidated together with it) makes this a deliberate tradeoff, best reserved for small icons/assets rather than large images. - Padding can sometimes be omitted safely if the decoder knows the exact input length by other means (common in URL-safe contexts), but standard MIME-context Base64 generally expects it — don't assume padding is optional without checking your specific decoder's requirements.
Fixing it
- URL-safe issues: swap
+//for-/_(and handle padding removal/restoration) using your language's URL-safe Base64 function — e.g., Python'sbase64.urlsafe_b64encode()/urlsafe_b64decode(), rather than the standard variant. - Missing padding on decode: most modern libraries have a lenient mode, or you can manually pad by appending
=characters until the string length is a multiple of 4 before decoding. - Command-line encode/decode:
base64 input.file > output.b64andbase64 -d output.b64 > input.file(flags vary slightly between GNU/BSDbase64implementations — check--decodevs-d). - Verifying you're not accidentally "securing" secrets with Base64 alone: if sensitive data (API keys, passwords, tokens) is only Base64-encoded and not also encrypted or hashed appropriately, that's a security gap, not a security measure — Base64 provides zero confidentiality.
Comparison
| Scheme | Key difference from Base64 |
|---|---|
| URL/percent-encoding | Encodes only the specific characters unsafe in URLs (as %XX sequences), rather than transforming the entire payload — see the URL encoding page |
| Base32 | Similar concept, coarser 5-bits-per-character alphabet — larger output, but case-insensitive and avoids visually similar characters, useful for things humans might need to type manually |
| Quoted-Printable | Also a MIME-era binary-to-text scheme, but optimized for content that's mostly already printable ASCII with occasional special bytes, rather than fully arbitrary binary — see the Quoted-Printable page |
| Hex encoding | Simpler 1-byte-to-2-characters mapping, larger output (100% size increase vs. Base64's ~33%), but trivially human-readable byte-by-byte |
FAQ
Is Base64 encryption?
No. Base64 is purely a representation format with no secret key — anyone can decode Base64 instantly using any standard library or even a browser console one-liner. It provides zero confidentiality and should never be relied on to protect sensitive data.
Why does my Base64 string have = signs at the end?
Padding. Base64 processes input in 3-byte groups producing 4 characters each; when the total input isn't a clean multiple of 3 bytes, = characters pad out the final group so a decoder knows exactly how many bytes of "real" data were in that last chunk versus padding.
Why does my Base64 string break when I put it in a URL?
Standard Base64 uses + and /, both of which have special meaning in URLs — + is interpreted as a space, and / is a path separator. Use the URL-safe Base64 variant instead, which substitutes - and _ for those two characters specifically so the output survives being placed directly in a URL.
Does Base64-encoding a file make it smaller?
No — the opposite. Base64 always increases size by roughly 33%, because 3 bytes of binary input become 4 ASCII characters of output. If you need smaller files, compress first (gzip, etc.) and only Base64-encode afterward if a text-safe transport format is genuinely required.
Fun fact
The 4:3 size expansion of Base64 is a mathematical inevitability, not an implementation quirk — it comes directly from needing 8 bits (a byte) to fit evenly into 6-bit groups (log2 of the 64-character alphabet). The lowest common multiple of 8 and 6 is 24, which is exactly where the "3 bytes → 4 characters" ratio comes from — there's no cleverer encoding that could do better while sticking to a printable-ASCII-only, fixed-alphabet design.