Back to Character Encoding

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's base64.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.b64 and base64 -d output.b64 > input.file (flags vary slightly between GNU/BSD base64 implementations — check --decode vs -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.