·10 min read·Encoding & Security

Base64 Encoding Explained: What It Is, How It Works, and When to Use It

Learn what Base64 encoding is, how the algorithm works step by step, and when to use it in web development. Covers data URIs, JWT tokens, email attachments, and API authentication with code examples in JavaScript and Python.

Try our free Base64 Encoder / Decoder

Encode & decode text, files, and images — with live preview. 100% client-side.

Open Tool

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 was originally designed to safely transmit binary data over channels that only support text — like email (SMTP), HTML, CSS, JSON, and URLs.

The name “Base64” comes from its use of a 64-character alphabet: the uppercase letters A-Z (26), lowercase a-z (26), digits 0-9 (10), and two special characters + and / (2). The = character is used for padding.

The formal specification is defined in RFC 4648. You encounter Base64 every day — in JWT tokens, data URIs, email attachments, HTTP Basic Auth headers, and embedded images in CSS. Understanding how it works will help you debug encoding issues, optimize payload sizes, and avoid common security mistakes.

How the Base64 Algorithm Works (Step by Step)

Let's encode the string Hi! to Base64 by hand. This walkthrough shows exactly what happens inside btoa() and every other Base64 encoder.

Step 1: Convert Characters to ASCII Values

H
ASCII 72
01001000
i
ASCII 105
01101001
!
ASCII 33
00100001

Step 2: Concatenate All Bits into One Stream

01001000 01101001 00100001
↓ join into one stream
010010000110100100100001

We now have 24 bits (3 bytes × 8 bits).

Step 3: Split into 6-Bit Groups

Base64 uses 6-bit groups instead of 8-bit bytes, because 26 = 64 — exactly the size of the Base64 alphabet.

010010 000110 100100 100001
  18      6     36     33

Step 4: Map Each 6-Bit Value to the Base64 Alphabet

Index 18
S
Index 6
G
Index 36
k
Index 33
h

Result

Input
Hi!
Base64 Output
SGkh

Three input bytes become four output characters — this is why Base64 always increases size by roughly 33%. The ratio is always 4:3. You can verify this result instantly with our Base64 Encoder.

The Base64 Alphabet

The standard Base64 alphabet (RFC 4648) consists of 64 characters plus a padding character:

Index RangeCharactersCount
0–25A B C ... Z26
26–51a b c ... z26
52–610 1 2 ... 910
62+1
63/1

Padding with =: When the input length isn't divisible by 3, Base64 adds = padding to make the output length a multiple of 4. One leftover byte produces ==, two leftover bytes produce =.

"A"     → "QQ=="   (1 byte  → 2 chars + 2 padding)
"AB"    → "QUI="   (2 bytes → 3 chars + 1 padding)
"ABC"   → "QUJD"   (3 bytes → 4 chars + 0 padding)
"ABCD"  → "QUJDRA==" (4 bytes → next multiple of 4)

6 Real-World Use Cases for Base64

1. Data URIs in HTML and CSS

Embed small images, fonts, or SVGs directly in HTML or CSS without a separate HTTP request. This eliminates a network round-trip and is ideal for icons under 2 KB.

<!-- Inline a 1x1 red pixel -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==" />

/* CSS background */
.icon { background-image: url("data:image/svg+xml;base64,PHN2Zy..."); }

2. JWT (JSON Web Tokens)

JWTs use Base64URL encoding (a URL-safe variant) to encode the header and payload. The three parts — header, payload, and signature — are each Base64URL-encoded and joined with dots.

// JWT structure:
// header.payload.signature
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U

// Decode the payload:
atob("eyJzdWIiOiIxMjM0NTY3ODkwIn0")
// → '{"sub":"1234567890"}'

3. Email Attachments (MIME)

Email protocols (SMTP) are text-based. Binary attachments like PDFs, images, and ZIP files are Base64-encoded before embedding in the email body. The Content-Transfer-Encoding: base64 header tells the mail client to decode them.

4. HTTP Basic Authentication

The HTTP Basic Auth scheme encodes the username:password pair in Base64 and sends it in the Authorization header. This is NOT encryption — always use HTTPS alongside Basic Auth.

// Authorization: Basic <base64(username:password)>
Authorization: Basic dXNlcjpwYXNzd29yZA==

// Decoded: "user:password"

5. Storing Binary Data in JSON or XML

JSON and XML cannot represent raw binary bytes. When you need to include binary data (like a cryptographic key, certificate, or small file) in a JSON payload, Base64 encoding is the standard approach.

{
  "certificate": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
  "format": "base64-der"
}

6. Encoding Data in URL Parameters

Base64URL encoding (replacing + with - and / with _) is used to safely pass binary or complex data in URL query parameters and path segments without conflicting with URL-reserved characters.

Want to decode a JWT token? Our JWT Decoder can decode the Base64URL-encoded header and payload instantly, with human-readable timestamps for expiry fields.

When NOT to Use Base64

Base64 is widely misused. Here are the most common mistakes:

Not for encryption or security

Base64 is trivially reversible. Anyone can decode it. Never use it to "hide" passwords, API keys, or sensitive data. Use AES-256, RSA, or bcrypt/scrypt for actual security.

Don't
"password": "cGFzc3dvcmQxMjM="
Do
"password": "$2b$12$LJ3m4..." (bcrypt hash)

Not for large files

The 33% size overhead makes Base64 unsuitable for large files. A 10 MB image becomes ~13.3 MB when Base64-encoded. Serve large assets as separate files with proper Content-Type headers instead.

Don't
50 KB icon as data URI in CSS (67 KB encoded)
Do
50 KB icon as separate .svg file with Cache-Control

Not for obfuscation

If you can see Base64-encoded data in your browser's DevTools, so can everyone else. It provides zero obfuscation against anyone who knows what Base64 looks like — which is every developer.

Don't
"apiKey": "c2VjcmV0LWtleS0xMjM=" in client-side JS
Do
Server-side env var + API proxy

Need actual hashing for passwords or data integrity? Check out our Hash Generator for MD5, SHA-256, SHA-512, and HMAC — and understand the difference between encoding, hashing, and encryption.

Base64 in Code: JavaScript, Python, and CLI

JavaScript (Browser)

// Encode
const encoded = btoa("Hello, World!");
// → "SGVsbG8sIFdvcmxkIQ=="

// Decode
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
// → "Hello, World!"

// ⚠️ btoa/atob only handle Latin-1 characters.
// For Unicode (emojis, CJK, etc.), use this:
function toBase64(str) {
  return btoa(String.fromCharCode(...new TextEncoder().encode(str)));
}

function fromBase64(b64) {
  return new TextDecoder().decode(
    Uint8Array.from(atob(b64), (c) => c.charCodeAt(0))
  );
}

toBase64("Hello 🌍");  // works with Unicode
fromBase64("SGVsbG8g8J+MjQ=="); // → "Hello 🌍"

Node.js

// Encode
const encoded = Buffer.from("Hello, World!").toString("base64");
// → "SGVsbG8sIFdvcmxkIQ=="

// Decode
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ==", "base64").toString("utf-8");
// → "Hello, World!"

// Encode a file
const fs = require("fs");
const imageBase64 = fs.readFileSync("photo.png").toString("base64");

Python

import base64

# Encode
encoded = base64.b64encode(b"Hello, World!").decode("utf-8")
# → "SGVsbG8sIFdvcmxkIQ=="

# Decode
decoded = base64.b64decode("SGVsbG8sIFdvcmxkIQ==").decode("utf-8")
# → "Hello, World!"

# URL-safe variant (for JWT, URL params)
url_safe = base64.urlsafe_b64encode(b"Hello, World!").decode("utf-8")
# → "SGVsbG8sIFdvcmxkIQ=="

Command Line (Linux / macOS)

# Encode a string
echo -n "Hello, World!" | base64
# → SGVsbG8sIFdvcmxkIQ==

# Decode a string
echo "SGVsbG8sIFdvcmxkIQ==" | base64 --decode
# → Hello, World!

# Encode a file
base64 photo.png > photo.b64

# Decode a file
base64 --decode photo.b64 > photo_restored.png

Don't want to write code? Our Base64 Encoder / Decoder handles text, files, and image previews — all in your browser with zero server calls.

Base64 vs Base64URL Encoding

Standard Base64 uses + and /, which are reserved characters in URLs. Base64URL (RFC 4648 Section 5) replaces them with URL-safe alternatives:

FeatureStandard Base64Base64URL
Character 62+- (hyphen)
Character 63/_ (underscore)
PaddingRequired (=)Often omitted
Used inEmail (MIME), data URIsJWT, URL params, filenames

JWT tokens always use Base64URL — that's why you can safely put them in URL query parameters and HTTP headers without additional URL-encoding. Our JWT Decoder handles Base64URL automatically. If you need to encode or decode URL parameters, check the String Encoder / Decoder which supports both URL encoding and Base64 in a pipeline.

Frequently Asked Questions

Is Base64 encoding the same as encryption?
No. Base64 is a reversible encoding scheme, not encryption. Anyone can decode it without a key. Never use Base64 to protect sensitive data — it provides zero security. Use proper encryption algorithms (AES, RSA) or hashing (bcrypt, SHA-256) instead.
Why does Base64 increase file size by 33%?
Base64 represents every 3 bytes of input as 4 ASCII characters. Each output character uses only 6 of its 8 available bits, creating a 4:3 ratio (33% overhead). For example, a 30 KB file becomes ~40 KB when Base64-encoded.
What is the difference between btoa() and atob() in JavaScript?
btoa() encodes a string to Base64 (binary-to-ASCII). atob() decodes Base64 back to the original string (ASCII-to-binary). Important caveat: btoa() only handles Latin-1 characters. For Unicode strings (emojis, CJK characters), you need to use TextEncoder first.
When should I use Base64 encoding?
Use Base64 when embedding binary data in text-only contexts: data URIs in HTML/CSS (small images, fonts), JWT token payloads, email attachments (MIME), HTTP Basic Auth headers, and binary data in JSON/XML. Avoid it for large files where the 33% size increase matters.

Encode & Decode Base64 Instantly

Paste text, drag a file, or drop an image — get instant Base64 encoding with live preview. Free, private, 100% browser-based.

Open Base64 Encoder / Decoder

Related Tools & Articles