Base64 shows up everywhere. JWTs use it for their header and payload sections. CSS data URIs embed images with it. HTTP Basic Auth encodes credentials in it. Email attachments use it. Yet despite being this ubiquitous, it's frequently misunderstood — people assume it provides some form of security, or they're fuzzy on why it exists at all. The encoding itself is formally defined in RFC 4648, which standardizes both Base64 and the URL-safe variant covered below.
Here's the full picture.
Why Base64 Exists
Binary data — images, audio files, compiled code — can contain any byte value from 0 to 255. Many text-based protocols and systems are designed to handle a much narrower range of safe characters. Email systems historically corrupted binary data that contained certain control bytes. URLs have characters with special meaning that can't appear unescaped. JSON strings can't contain raw binary.
Base64 solves this by converting arbitrary binary data into a string using only 64 printable ASCII characters: A-Z, a-z, 0-9, +, and /. The = character is used for padding. That "alphabet" of 64 safe characters is what gives the encoding its name. The original motivation is captured in the MIME spec (RFC 2045), which formalized Base64 for safely passing binary data through email gateways that only handled 7-bit ASCII.
The result can travel safely through any system that handles ASCII text, regardless of what the original binary contained.
How the Algorithm Works
The encoding process takes 3 bytes of input at a time and converts them into 4 output characters.
3 bytes = 24 bits. Split those 24 bits into four groups of 6 bits each. Each 6-bit group can represent a value from 0 to 63 — which maps to one of the 64 characters in the Base64 alphabet.
Let's trace "Man" as an example:
M a n
01001101 01100001 01101110 (binary)
010011 010110 000101 101110 (split into 6-bit groups)
19 22 5 46 (decimal values)
T W F u (Base64 alphabet lookup)
So "Man" encodes to "TWFu". You can verify this yourself with the Base64 Encoder.
Padding
If the input isn't a multiple of 3 bytes, padding characters (=) are added:
- 1 leftover byte → 2 Base64 characters +
== - 2 leftover bytes → 3 Base64 characters +
=
"Ma" (2 bytes) encodes to "TWE=". "M" (1 byte) encodes to "TQ==".
The Size Cost
Converting 3 bytes to 4 characters means Base64 always increases size by approximately 33%. A 100KB image becomes ~133KB when Base64-encoded. For a 1MB PDF, that's an extra ~333KB.
This matters when you're deciding whether to inline images as data URIs or serve them as separate requests. For small icons (under a few hundred bytes), inlining wins — you save an HTTP round-trip. For anything larger, the size penalty usually outweighs the savings.
Base64 vs Base64url
Standard Base64 uses + and / as characters 62 and 63, and = for padding. These characters have special meanings in URLs and HTTP headers — + means a space in form encoding, / is a path separator.
Base64url is a URL-safe variant that replaces:
+with-/with_- Strips the
=padding
This is what JWTs use (RFC 7515 §C explicitly mandates the URL-safe alphabet). The three sections of a JWT — header, payload, and signature — are all Base64url-encoded, not standard Base64. If you try to decode a JWT section with a standard Base64 decoder and it fails, that's why. The Base64 Encoder tool handles both variants.
Standard Base64 and Base64url encode to different strings but decode to the same bytes. They're not different encoding schemes — just different alphabets for the same algorithm.
Common Use Cases
JWTs
As covered in JWT Tokens Explained, the header and payload of a JWT are Base64url-encoded JSON objects. They're not encrypted — anyone can decode them. The signature is what prevents tampering.
HTTP Basic Authentication
The Authorization: Basic <credentials> header contains username:password encoded in Base64:
username:password → dXNlcm5hbWU6cGFzc3dvcmQ=
This is encoding, not encryption. Anyone who intercepts the header can trivially decode it. Basic Auth should only ever be used over HTTPS.
CSS Data URIs
You can embed an image directly in a stylesheet without a separate HTTP request:
background-image: url("data:image/png;base64,iVBORw0KGgo...");
The browser decodes the Base64 string to get the raw image bytes. Useful for small icons and background images to eliminate extra HTTP requests, though the 33% size overhead means it's only worth it for small assets.
Email Attachments (MIME)
The MIME standard uses Base64 to encode binary attachments in email messages. When you open an email attachment, your client is decoding a Base64 string to reconstruct the original file. This is why email has been transporting files safely since long before HTTP file uploads were reliable.
Storing Binary Data in JSON or Text Formats
JSON has no binary type. If you need to include binary data in a JSON payload — an image thumbnail, a cryptographic key, a certificate — Base64 encoding is the standard approach.
What Base64 Is Not
Base64 is not encryption. It provides no security whatsoever.
Anyone can reverse it without a key. It obscures content from a casual glance, but any developer can decode it in seconds. Don't use it to hide passwords, API keys, or sensitive data — you're not protecting anything, you're just making it slightly less readable.
For actual security, you need:
- Encryption — transforms data with a key so only key holders can reverse it
- Hashing — one-way transformation for integrity checking and password storage
The Hash Generator handles cryptographic hashing. For actual encryption needs, look to established libraries (libsodium, OpenSSL, Web Crypto API) with properly chosen algorithms.
Encoding URLs and Query Parameters
Base64 is sometimes confused with URL encoding, which is a different thing entirely. URL encoding (percent-encoding) escapes characters that have special meaning in URLs using %XX hex codes. The URL Encoder handles this case.
The distinction matters when you're passing Base64-encoded data as a URL parameter. Standard Base64 output contains +, /, and = — all of which need to be URL-encoded if they appear in a query string. Base64url output avoids this problem entirely, which is another reason it's preferred for anything HTTP-related.
Decoding in Practice
Most languages have Base64 support built in or in a standard library. In browsers, MDN's `btoa()` reference covers gotchas around non-ASCII input:
// Browser / Node.js
btoa("hello") // encode → "aGVsbG8="
atob("aGVsbG8=") // decode → "hello"
// For binary data in Node.js
Buffer.from(data).toString("base64")
Buffer.from(encoded, "base64")
import base64
base64.b64encode(b"hello") # b'aGVsbG8='
base64.b64decode(b"aGVsbG8=") # b'hello'
# URL-safe variant
base64.urlsafe_b64encode(b"hello")
The base64.guru reference covers encoding details and edge cases for various implementations.
For more on encoding schemes that come up alongside Base64, read Encoding vs Encryption vs Hashing — the distinctions between these three concepts are worth knowing clearly.
Wrapping Up
Base64 is an encoding scheme for making binary data text-safe — nothing more. It's everywhere because text-based protocols are everywhere. The 33% size overhead is the cost of portability. The security situation is simple: it provides none. When you need to encode and decode Base64 quickly without writing code, the Base64 Encoder handles both standard and URL-safe variants.
FAQ
Is Base64 a form of encryption?
No, and this is the most common misconception. Base64 is fully reversible by anyone — no key, no secret, no math beyond simple table lookup. Encoding a password as Base64 stores it in plaintext as far as security is concerned. Use Base64 for format compatibility (binary in JSON, data in URLs), never for confidentiality.
Why does Base64 add 33% to the size?
Because it represents 6 bits of data with 8 bits of output (one ASCII character per 6 bits). 3 input bytes (24 bits) become 4 output characters (32 bits) — a fixed 4:3 ratio that means roughly 33% overhead, plus a tiny bit more for padding. There's no way to do this more efficiently with the same printable alphabet.
Should I use Base64 or Base64url for URLs and JWTs?
Base64url. Standard Base64 contains +, /, and = — all of which have special meaning in URLs and need percent-encoding to survive in query strings or fragments. Base64url replaces + with -, / with _, and drops the = padding, so the output is URL-safe by default. JWT specifies Base64url specifically.
Can I shave off the `=` padding from a Base64 string?
Sometimes. Base64url strips it; standard Base64 keeps it. Most decoders accept missing padding gracefully (computing the length from the input), but some are strict. For interop, prefer including padding for standard Base64 and omitting it only when using Base64url. When in doubt, keep the = characters.
When should I inline an image as a Base64 data URI vs. linking it?
Inline only for small images (under ~2KB) where saving a network round-trip outweighs the 33% size penalty and lost cacheability. Inlined images can't be cached separately by the browser, so they're re-downloaded with every page that includes them. SVG icons under 1KB are good candidates; anything larger should be a separate file.
Why does my decoded Base64 contain garbage when the source looked fine?
Three common causes: (1) Base64url vs standard Base64 mismatch — -_ characters fail in standard decoders, (2) the string contains whitespace or line breaks that confuse strict decoders, (3) the input is double-encoded (encoded twice somehow). Strip whitespace, normalize the alphabet (- → +, _ → /), and decode again.
Is Base64 the same as Base32 or Base58?
All three are encodings, but they use different alphabets and have different use cases. Base32 uses 32 case-insensitive characters (A-Z, 2-7), making it manually typeable; used in TOTP secrets. Base58 (Bitcoin addresses) excludes visually similar characters (0/O, 1/l/I). Base64 is the most compact but case-sensitive and includes some special characters.
Can Base64 be used to compress data?
No — it's the opposite. Base64 always expands data by 33%. If you want to send binary data smaller, compress it first (gzip, brotli, zstd) and then Base64-encode the compressed bytes. The combined "compress then encode" workflow is common for transmitting binary blobs through text-only channels like email or JSON APIs.