Base64 Encode & Decode: Complete Guide with Examples (2026)
Base64 encoding is everywhere — in email attachments, data URIs, API authentication headers, and embedded images. This guide explains exactly what Base64 is, how it works under the hood, when to use it (and when not to), and how to encode and decode Base64 in every major programming language.
Need to Encode or Decode Base64 Right Now?
Paste any text or Base64 string into our free tool. Instant results, no signup required.
Open Free Base64 ToolWhat Is Base64 Encoding?
Base64 is a binary-to-text encoding scheme that represents binary data using a set of 64 printable ASCII characters. It was originally designed to allow binary data to be transmitted over systems that only support text, such as email (SMTP) and early HTTP.
The name "Base64" comes from the fact that the encoding uses exactly 64 characters to represent data. These 64 characters are:
- Uppercase letters:
AthroughZ(26 characters) - Lowercase letters:
athroughz(26 characters) - Digits:
0through9(10 characters) - Two special characters:
+and/ - A padding character:
=
The standard Base64 alphabet is defined in RFC 4648, which is the authoritative specification for Base64 encoding. There is also a "URL-safe" variant that replaces + with - and / with _ to avoid conflicts in URLs and filenames.
Important: Base64 is not encryption. It provides zero security. Anyone can decode a Base64 string instantly. Never use Base64 to "hide" passwords, API keys, or sensitive data. If you see credentials stored as Base64, they are effectively stored in plain text.
How Base64 Encoding Works (Step by Step)
Understanding the algorithm makes it much easier to debug encoding issues. Here is exactly how Base64 converts binary data to text:
Step 1: Convert Input to Binary
Take the input data and represent it as a sequence of bytes (8-bit binary values). For text input, this means converting each character to its ASCII or UTF-8 byte value.
For example, the string Hi! becomes:
H = 72 = 01001000 i = 105 = 01101001 ! = 33 = 00100001
Step 2: Split Into 6-Bit Groups
Concatenate all the binary bits and split them into groups of 6 bits (instead of the usual 8). This is the core of the algorithm — each 6-bit group maps to exactly one Base64 character.
01001000 01101001 00100001 ↓ 010010 000110 100100 100001
Since 6 bits can represent values from 0 to 63, this gives us exactly 64 possible values — hence the name Base64.
Step 3: Map to Base64 Characters
Each 6-bit value is looked up in the Base64 alphabet table:
010010 = 18 → S 000110 = 6 → G 100100 = 36 → k 100001 = 33 → h
So Hi! encodes to SGkh.
Step 4: Add Padding If Needed
Base64 works on groups of 3 input bytes (24 bits) at a time. If the input length is not a multiple of 3, padding characters (=) are added to the output:
- If 1 byte is left over: add
==(two padding characters) - If 2 bytes are left over: add
=(one padding character) - If exactly divisible by 3: no padding needed
"A" → "QQ==" (1 byte → 2 padding chars) "AB" → "QUI=" (2 bytes → 1 padding char) "ABC" → "QUJD" (3 bytes → no padding) "ABCD"→ "QUJDRA==" (4 bytes → starts new group)
Tip: You can always tell how many "extra" bytes were in the original data by counting the = signs at the end. Two equals signs means one extra byte; one equals sign means two extra bytes. This is useful for debugging encoding issues.
Base64 vs URL-Safe Base64 vs Other Variants
Not all Base64 is the same. There are several variants, and using the wrong one is a common source of bugs.
| Variant | Characters 62 & 63 | Padding | Use Case |
|---|---|---|---|
| Standard (RFC 4648) | + and / |
Required (=) |
Email (MIME), general encoding |
| URL-Safe (RFC 4648 §5) | - and _ |
Often omitted | URLs, filenames, JWT tokens |
| MIME (RFC 2045) | + and / |
Required | Email attachments, line-wrapped at 76 chars |
The most common mistake is using standard Base64 in URLs. The + character gets interpreted as a space, and / is a path separator. Always use URL-safe Base64 when the encoded string will appear in a URL, query parameter, or filename.
Common Use Cases for Base64
Base64 appears in more places than most developers realize. Here are the most common real-world use cases.
1. Data URIs (Embedding Images in HTML/CSS)
Data URIs let you embed small files directly in your HTML or CSS, eliminating an HTTP request. The format is:
data:[mediatype];base64,[encoded-data]Embedding a small image in HTML:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHx gljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
Best practice: Only use data URIs for very small files (under 2–5 KB). For larger images, a separate file with proper caching is more efficient. Remember, Base64 adds ~33% overhead, and the browser cannot cache inline data URIs separately from the HTML.
2. Email Attachments (MIME)
SMTP email was designed for 7-bit ASCII text. To attach a PDF, image, or any binary file, email clients Base64-encode the file and embed it in the message body with MIME headers. When you send an email with an attachment, this happens automatically behind the scenes.
3. HTTP Basic Authentication
HTTP Basic Auth transmits credentials as a Base64-encoded username:password string in the Authorization header:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Decoding dXNlcm5hbWU6cGFzc3dvcmQ= gives username:password. This is why Basic Auth should always be used over HTTPS — the Base64 encoding provides zero security.
4. JWT Tokens
JSON Web Tokens (JWTs) consist of three Base64URL-encoded parts separated by dots: header.payload.signature. The header and payload are just JSON objects encoded with URL-safe Base64. You can decode the first two parts of any JWT to read its contents (the signature part requires the secret key to verify, not decode).
5. Storing Binary Data in JSON or XML
JSON and XML are text formats that cannot directly represent binary data. If you need to include an image, certificate, or binary blob in a JSON API response, Base64 encoding is the standard approach. Many APIs including Stripe, GitHub, and AWS return binary data as Base64 strings within JSON.
6. Embedding Fonts and SVGs in CSS
Web fonts and SVG icons can be Base64-encoded and embedded directly in CSS stylesheets using @font-face or background-image data URIs. This reduces the number of network requests at the cost of larger CSS files and lost caching benefits.
Base64 Encoding in JavaScript
JavaScript provides built-in Base64 functions in both browser and Node.js environments, but they work differently.
Browser (btoa and atob)
Encoding a string:const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="
Decoding a Base64 string:
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"
Watch out: btoa() only handles Latin-1 characters. If your string contains Unicode characters (emoji, CJK, accented characters), it will throw an error. Use the UTF-8 safe method below instead.
Handling Unicode Strings (Browser)
UTF-8 safe Base64 encode/decode:// Encode (handles Unicode)
function utf8ToBase64(str) {
return btoa(
encodeURIComponent(str).replace(
/%([0-9A-F]{2})/g,
(_, p1) => String.fromCharCode(parseInt(p1, 16))
)
);
}
// Decode
function base64ToUtf8(base64) {
return decodeURIComponent(
atob(base64).split('').map(
c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0')
).join('')
);
}
utf8ToBase64("Hello! Bonjour!"); // Works with Unicode
Node.js (Buffer)
Encoding and decoding in Node.js:// Encode string to Base64
const encoded = Buffer.from("Hello, World!").toString("base64");
// "SGVsbG8sIFdvcmxkIQ=="
// Decode Base64 to string
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ==", "base64").toString();
// "Hello, World!"
// URL-safe Base64
const urlSafe = Buffer.from("Hello, World!").toString("base64url");
// "SGVsbG8sIFdvcmxkIQ"
// Encode a file to Base64
const fs = require("fs");
const fileBase64 = fs.readFileSync("image.png").toString("base64");
Base64 Encoding in Python
Python's standard library includes the base64 module with functions for all Base64 variants.
import base64 # Encode encoded = base64.b64encode(b"Hello, World!") print(encoded) # b'SGVsbG8sIFdvcmxkIQ==' # Decode decoded = base64.b64decode(b"SGVsbG8sIFdvcmxkIQ==") print(decoded) # b'Hello, World!' # URL-safe variant url_safe = base64.urlsafe_b64encode(b"Hello, World!") print(url_safe) # b'SGVsbG8sIFdvcmxkIQ=='Encoding a file:
import base64
# Read and encode an image file
with open("photo.jpg", "rb") as f:
encoded = base64.b64encode(f.read()).decode("ascii")
# Create a data URI
data_uri = f"data:image/jpeg;base64,{encoded}"
# Decode and write back to a file
with open("output.jpg", "wb") as f:
f.write(base64.b64decode(encoded))
Base64 on the Command Line
Every major operating system has built-in Base64 command-line tools.
Linux / macOS
# Encode a string echo -n "Hello, World!" | base64 # SGVsbG8sIFdvcmxkIQ== # Decode a string echo "SGVsbG8sIFdvcmxkIQ==" | base64 --decode # Hello, World! # Encode a file base64 image.png > image_base64.txt # Decode a file base64 --decode image_base64.txt > image_restored.png
Windows (PowerShell)
# Encode
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("Hello, World!"))
# SGVsbG8sIFdvcmxkIQ==
# Decode
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("SGVsbG8sIFdvcmxkIQ=="))
# Hello, World!
Tip: On Linux, use echo -n (not just echo) when encoding. Without -n, echo adds a newline character that becomes part of the encoded output, giving you an incorrect result.
Base64 in Other Languages
Java
import java.util.Base64;
// Encode
String encoded = Base64.getEncoder().encodeToString("Hello".getBytes());
// Decode
byte[] decoded = Base64.getDecoder().decode(encoded);
String original = new String(decoded);
// URL-safe
String urlSafe = Base64.getUrlEncoder().encodeToString("Hello".getBytes());
PHP
// Encode
$encoded = base64_encode("Hello, World!");
// "SGVsbG8sIFdvcmxkIQ=="
// Decode
$decoded = base64_decode("SGVsbG8sIFdvcmxkIQ==");
// "Hello, World!"
Go
import "encoding/base64"
// Encode
encoded := base64.StdEncoding.EncodeToString([]byte("Hello"))
// Decode
decoded, err := base64.StdEncoding.DecodeString(encoded)
// URL-safe
urlSafe := base64.URLEncoding.EncodeToString([]byte("Hello"))
The 33% Size Overhead: When to Use Base64 (and When Not To)
Every 3 bytes of input become 4 bytes of Base64 output. That is a 33.3% increase in size. For small data like authentication tokens or tiny icons, this overhead is negligible. For large files, it matters.
| Original Size | Base64 Size | Overhead |
|---|---|---|
| 100 bytes | 136 bytes | +36 bytes |
| 1 KB | 1.33 KB | +0.33 KB |
| 1 MB | 1.33 MB | +0.33 MB |
| 10 MB | 13.3 MB | +3.3 MB |
When to use Base64:
- Embedding small images or icons in HTML/CSS (under 2–5 KB)
- Transmitting binary data through text-only protocols (email, JSON APIs)
- HTTP authentication headers
- Storing small binary blobs in databases that only support text
- Creating self-contained HTML files with embedded resources
When NOT to use Base64:
- Storing large files (use binary storage or object storage like S3)
- Embedding large images in HTML (use separate files with CDN caching)
- Security purposes (it is not encryption)
- Compressing data (it makes data larger, not smaller)
Debugging Common Base64 Issues
Base64 encoding problems can be tricky because the output always looks valid but the decoded result may be wrong. Here are the most common issues and their fixes.
Problem: Unexpected Whitespace or Newlines
MIME-style Base64 wraps lines at 76 characters. If you are feeding MIME-encoded data to a strict decoder, strip whitespace first. Conversely, if you are generating Base64 for email, you may need to add line breaks.
Problem: Unicode Characters Cause Errors
The browser's btoa() function only handles Latin-1. For Unicode text, encode to UTF-8 bytes first, then Base64-encode those bytes. See the JavaScript section above for the correct approach.
Problem: URL-Safe vs Standard Mismatch
If you encode with standard Base64 but the data is used in a URL, the + and / characters will be corrupted. Always match the Base64 variant to the transport method. Convert between variants by replacing + with -, / with _, and removing = padding.
Problem: Padding Errors
Some decoders are strict about padding and will reject Base64 strings where the padding is missing. If you receive a Base64 string without padding (common in JWTs and URL-safe contexts), add the missing = characters:
// JavaScript: Add missing padding
function addPadding(base64) {
const pad = base64.length % 4;
if (pad === 2) return base64 + "==";
if (pad === 3) return base64 + "=";
return base64;
}
Base64 Quick Reference
- Base64 uses 64 ASCII characters (A-Z, a-z, 0-9, +, /) plus = for padding
- URL-safe Base64 replaces + with - and / with _ (use this for URLs and JWTs)
- Output is always ~33% larger than the input
- Every 3 input bytes produce exactly 4 output characters
- Base64 is encoding, NOT encryption — never use it for security
- Use data URIs only for small files (under 5 KB)
- Browser btoa()/atob() do not support Unicode — encode to UTF-8 first
- Node.js Buffer supports base64 and base64url encodings natively
- Python's base64 module handles all variants (standard, URL-safe, MIME)
- Always use echo -n on Linux to avoid encoding an extra newline
Frequently Asked Questions
What is Base64 encoding?
Base64 is a binary-to-text encoding scheme that converts binary data into a string of 64 printable ASCII characters. It is used to safely transmit binary data over text-based systems like email, HTML, URLs, and JSON APIs.
Is Base64 encryption?
No. Base64 is an encoding scheme, not encryption. It does not provide any security. Anyone can decode a Base64 string back to its original data without a key. Never use Base64 to hide passwords, tokens, or sensitive data.
Why does Base64 increase file size?
Base64 encodes every 3 bytes of binary data into 4 ASCII characters, resulting in approximately 33% larger output. This overhead is the trade-off for being able to safely transmit binary data through text-only channels.
How do I Base64 encode a string in JavaScript?
In the browser, use btoa() to encode and atob() to decode. For Node.js, use Buffer.from(string).toString('base64') to encode and Buffer.from(base64String, 'base64').toString() to decode. For Unicode strings, encode to UTF-8 first using TextEncoder.
What are data URIs and how do they use Base64?
Data URIs embed file content directly into HTML or CSS using the format data:[mediatype];base64,[data]. For example, a small PNG image can be embedded as data:image/png;base64,iVBORw0KGgo... This eliminates an extra HTTP request but increases HTML size by about 33%.
Encode or Decode Base64 Instantly
Our free Base64 encoder/decoder tool runs entirely in your browser. Paste any text to encode it to Base64, or paste a Base64 string to decode it back to plain text. No signup, no data sent to any server, works on desktop and mobile.
Open the Free Base64 Tool →Related guides: JSON Formatting Guide · UTM Parameters Guide · Meta Tags SEO Guide · Robots.txt Guide