Base64 shows up in emails, JWTs, data URIs, and HTTP basic auth. But what exactly is it, and when should you use it?
What Is Base64?
Base64 is an encoding scheme that converts binary data into a string of 64 printable ASCII characters. The character set is:
A–Z (26)
a–z (26)
0–9 (10)
+ / (2)
= (padding)
It’s not encryption — it’s encoding. Anyone can decode it.
Why Does Base64 Exist?
Binary data (images, files, arbitrary bytes) cannot safely travel through systems that only handle text — email protocols, XML, JSON, HTTP headers. Base64 bridges that gap by representing binary as plain text.
Common use cases:
- Embedding images in HTML/CSS:
src="data:image/png;base64,..." - JWT tokens: header and payload sections are Base64URL encoded
- HTTP Basic Auth:
Authorization: Basic dXNlcjpwYXNz - Email attachments: MIME encoding
- Storing binary in JSON: APIs that return images as Base64 strings
How Base64 Encoding Works
Base64 takes 3 bytes (24 bits) at a time and splits them into four 6-bit groups. Each 6-bit value maps to one character in the 64-character alphabet.
Input: M a n
Bytes: 77 97 110
Binary: 01001101 01100001 01101110
Split: 010011 010110 000101 101110
Index: 19 22 5 46
Output: T W F u
If the input isn’t divisible by 3, = padding is added to make the output length a multiple of 4.
Base64 Encoding Online
The fastest way to encode or decode Base64 in your browser:
Try the ZeroTool Base64 Encoder/Decoder →
Paste text or a URL, encode or decode instantly, copy with one click. No install required.
Encoding and Decoding in Code
JavaScript (Browser)
// Encode
const encoded = btoa('Hello, World!');
// SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
// Hello, World!
Note: btoa / atob only handle Latin-1. For Unicode strings:
// Encode Unicode
const encoded = btoa(unescape(encodeURIComponent('こんにちは')));
// Decode Unicode
const decoded = decodeURIComponent(escape(atob(encoded)));
JavaScript (Node.js)
// Encode
const encoded = Buffer.from('Hello, World!').toString('base64');
// Decode
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
Python
import base64
# Encode
encoded = base64.b64encode(b'Hello, World!').decode('utf-8')
# SGVsbG8sIFdvcmxkIQ==
# Decode
decoded = base64.b64decode('SGVsbG8sIFdvcmxkIQ==').decode('utf-8')
# Hello, World!
Command Line
# Encode
echo -n 'Hello, World!' | base64
# SGVsbG8sIFdvcmxkIQ==
# Decode
echo 'SGVsbG8sIFdvcmxkIQ==' | base64 --decode
# Hello, World!
On macOS, use base64 -D instead of --decode.
Base64URL: The URL-Safe Variant
Standard Base64 uses + and /, which have special meaning in URLs. Base64URL replaces them:
| Standard | Base64URL |
|---|---|
+ | - |
/ | _ |
= padding | omitted (optional) |
JWTs use Base64URL. If you see a JWT like eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.xxx, each .-separated section is a Base64URL-encoded string.
// Node.js Base64URL encode
const encoded = Buffer.from(data).toString('base64url');
Size Overhead
Base64 increases data size by ~33% (3 bytes become 4 characters). For large files — images, videos — this overhead matters. Don’t use Base64 where a direct binary transfer or URL reference is possible.
| Original size | Base64 size |
|---|---|
| 1 KB | ~1.37 KB |
| 1 MB | ~1.37 MB |
| 10 MB | ~13.7 MB |
When NOT to Use Base64
- File downloads — serve the file directly; Base64 in JSON is wasteful
- Passwords — Base64 is not encryption; use proper hashing (bcrypt, argon2)
- Large binary transfers — prefer multipart form data or binary protocols
Summary
| Task | Method |
|---|---|
| Quick encode/decode | ZeroTool Base64 Tool |
| Browser JS | btoa() / atob() |
| Node.js | Buffer.from(...).toString('base64') |
| Python | base64.b64encode() / base64.b64decode() |
| CLI | base64 / base64 --decode |
| URL-safe variant | Base64URL (- and _ instead of + and /) |
Base64 is a fundamental tool in a developer’s toolkit — understanding when and how to use it prevents subtle bugs in APIs, auth headers, and data pipelines.