All Articles

What is Base64 Encoding? Everything You Need to Know

·14 min read

What is Base64?

Base64 is a binary-to-text encoding scheme that represents binary data using a set of 64 printable ASCII characters. It was designed to carry binary data across channels that only reliably support text content — think email protocols, JSON payloads, HTML attributes, and URL parameters.

The name "Base64" comes from the fact that the encoding uses a 64-character alphabet. This alphabet consists of the uppercase letters A–Z (26), lowercase letters a–z (26), digits 0–9 (10), and two additional characters, typically + and /, plus = for padding. The result is a string that can safely pass through any system that handles plain text.

Why Does Base64 Exist?

Many protocols and systems were designed in an era when only 7-bit ASCII text was considered safe to transmit. Binary data — images, executables, compressed archives — contains byte values that can include control characters, null bytes, and values above 127 that can be mangled or misinterpreted by text-based systems.

Base64 solves this by converting every 3 bytes of binary data into 4 printable ASCII characters, ensuring the data survives intact through:

How Base64 Encoding Works

The Base64 algorithm is elegant in its simplicity. Here is the step-by-step process:

Step 1: Convert Input to Binary

Take the input data and represent it as a stream of bytes. For text input, this means using a character encoding like UTF-8. For example, the string Hi! becomes three bytes: 01001000 01101001 00100001.

Step 2: Split Into 6-Bit Groups

Concatenate all the bits and divide them into groups of 6 bits (since 2⁶ = 64, each group maps to one of the 64 characters). Our 24 bits become four groups: 010010, 000110, 100100, 100001.

Step 3: Map to the Base64 Alphabet

Each 6-bit value (0–63) maps to a character in the Base64 alphabet table:

Index:  0  = A     17 = R     34 = i     51 = z
        1  = B     18 = S     35 = j     52 = 0
        2  = C     19 = T     36 = k     53 = 1
        ...
        25 = Z     26 = a     52 = 0     62 = +
                                         63 = /

Our four 6-bit groups (18, 6, 36, 33) map to S, G, k, h. So Hi! encodes to SGkh.

Step 4: Handle Padding

Base64 operates on 3-byte blocks. If the input length isn't a multiple of 3, the output is padded with = characters:

// Examples showing padding
"A"   → "QQ=="    (1 byte  → 2 chars + ==)
"Hi"  → "SGk="    (2 bytes → 3 chars + =)
"Hi!" → "SGkh"    (3 bytes → 4 chars, no padding)

Base64 in Practice: Common Use Cases

Data URIs in HTML and CSS

Data URIs let you embed files directly into HTML or CSS, eliminating an HTTP request. This is especially useful for small icons, SVGs, and fonts:

<!-- Embedding a small PNG icon -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="icon" />

/* Embedding a font in CSS */
@font-face {
  font-family: 'MyFont';
  src: url('data:font/woff2;base64,d09GMgABAAA...') format('woff2');
}

Our Image to Base64 tool converts any image file to a ready-to-use data URI string.

API Authentication Tokens

HTTP Basic Authentication encodes the username and password in Base64:

// HTTP Basic Auth header
const credentials = btoa("username:password");
fetch("/api/data", {
  headers: {
    Authorization: `Basic ${credentials}`
  }
});

This is not encryption — anyone who intercepts the header can decode it instantly. Basic Auth should only be used over HTTPS.

JSON Web Tokens (JWTs)

JWTs are perhaps the most visible use of Base64 in modern web development. A JWT consists of three Base64URL-encoded parts separated by dots:

header.payload.signature

// Example JWT (truncated)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

You can decode the header and payload of any JWT using our JWT Decoder to inspect its claims without writing any code. The payload is just Base64URL-encoded JSON.

Email Attachments (MIME)

When you send an email with an attachment, the email client encodes the file in Base64 and includes it in the MIME body. This is the original use case that drove the creation of Base64 encoding — SMTP email transport was designed for 7-bit ASCII text only.

Storing Binary Data in JSON or XML

When an API needs to include binary data (like a thumbnail, a PDF, or a cryptographic signature) in a JSON response, Base64 encoding is the standard approach:

{
  "user": "alice",
  "avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
  "certificate": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
}

Encoding vs Encryption: A Critical Distinction

This is one of the most common misconceptions in web development: Base64 is encoding, not encryption. The difference is fundamental:

Never use Base64 to "secure" sensitive data. Anyone can decode Base64 instantly. If you need to protect data, use proper encryption (AES-256-GCM, for example) and encode the encrypted result in Base64 for transport.

You can verify this yourself: paste any Base64 string into our Base64 Encoder/Decoder and see the original data instantly.

URL-Safe Base64

Standard Base64 uses + and / characters, which have special meanings in URLs (+ is often interpreted as a space, and / is a path separator). URL-safe Base64 (also called Base64URL) replaces these:

// Standard Base64
"Hello?World" → "SGVsbG8/V29ybGQ="

// URL-safe Base64
"Hello?World" → "SGVsbG8_V29ybGQ"

// Converting between variants
const urlSafe = standard
  .replace(/\+/g, '-')
  .replace(/\//g, '_')
  .replace(/=+$/, '');

JWTs use Base64URL encoding exclusively, which is why you never see +, /, or = in a JWT string.

Base64 in JavaScript

JavaScript provides built-in functions for Base64 encoding and decoding:

// Browser: btoa() and atob()
const encoded = btoa("Hello, World!");  // "SGVsbG8sIFdvcmxkIQ=="
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");  // "Hello, World!"

// Node.js: Buffer
const encoded = Buffer.from("Hello, World!").toString("base64");
const decoded = Buffer.from(encoded, "base64").toString("utf-8");

// Handling Unicode (btoa only supports Latin1)
const unicodeStr = "Hello, 世界! 🌍";
const encoded = btoa(unescape(encodeURIComponent(unicodeStr)));
const decoded = decodeURIComponent(escape(atob(encoded)));

Note that btoa() and atob() only handle Latin1 characters. For Unicode strings, you need the encodeURIComponent workaround shown above, or use the TextEncoder API in modern browsers.

Base64 in Python

import base64

# Encoding
data = "Hello, World!"
encoded = base64.b64encode(data.encode()).decode()
print(encoded)  # "SGVsbG8sIFdvcmxkIQ=="

# Decoding
decoded = base64.b64decode(encoded).decode()
print(decoded)  # "Hello, World!"

# URL-safe variant
url_encoded = base64.urlsafe_b64encode(data.encode()).decode()
print(url_encoded)  # "SGVsbG8sIFdvcmxkIQ=="

# Encoding a file
with open("image.png", "rb") as f:
    encoded_image = base64.b64encode(f.read()).decode()

Performance Considerations

Base64 encoding increases data size by approximately 33% — every 3 bytes of input become 4 bytes of output. This overhead matters in several contexts:

Rule of thumb: use Base64 for data under 10 KB (icons, small config blobs, tokens). For anything larger, serve the binary data directly.

Common Mistakes with Base64

Using Base64 for Security

As emphasized earlier, Base64 is not encryption. Never store passwords, API keys, or secrets as "just Base64" and consider them protected. Use proper cryptographic methods.

Double Encoding

A common bug is accidentally encoding data twice, producing invalid results. If you Base64-encode a string that's already Base64-encoded, you get a longer string that needs to be decoded twice. Always know the state of your data.

Ignoring Character Encoding

Base64 operates on bytes, not characters. If you encode a Unicode string, the result depends on the character encoding used (UTF-8, UTF-16, etc.). Always be explicit about encoding when converting strings to bytes.

Not Handling Padding

Some Base64 implementations strip padding, while others require it. If you're interoperating between systems, verify whether padding is expected. Most decoders handle both padded and unpadded input, but not all.

Quick Reference: When to Use Base64

Need to quickly encode or decode Base64? Try our Base64 Encoder/Decoder — it handles standard and URL-safe variants, supports file uploads, and shows the result in real time.

Wrapping Up

Base64 is one of those foundational technologies that most developers use daily without thinking much about. Understanding how it works — the 6-bit grouping, the 33% size overhead, the critical distinction from encryption — makes you a more effective debugger and a more informed architect. The next time you see a mysterious string of letters and numbers ending in =, you'll know exactly what it is and how to decode it.

Try These Tools

Related Articles

Enjoy this article? Buy us a coffee to support free tools and guides.