·12 min read

Base64 Encoding Explained: A Complete Guide for Developers

Base64 encoding is one of those things every developer encounters but few truly understand. Whether you are embedding images in HTML, working with JWTs, or sending binary data over an API, Base64 is everywhere. This guide covers everything you need to know — from the underlying algorithm to practical code examples.

What 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 for transmitting binary data over channels that only reliably support text content, such as email (MIME) and older HTTP implementations.

The name “Base64” comes from the fact that it uses exactly 64 characters to represent data. These 64 characters consist of uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and two additional symbols: + and /. A 65th character, =, is used as a padding suffix.

It is important to understand that Base64 is not encryption. It does not provide any security. It is simply an encoding — a way to represent binary data as text. Anyone can decode a Base64 string back to its original form without any key or secret.

How Base64 Encoding Works

The Encoding Process

Base64 encoding converts every 3 bytes (24 bits) of binary input into 4 Base64 characters (each representing 6 bits). Here is a step-by-step breakdown:

  1. Take 3 bytes of input — this gives you 24 bits of binary data.
  2. Split into four 6-bit groups — each 6-bit group can represent a value from 0 to 63.
  3. Map each group to a Base64 character — using the Base64 alphabet table (A=0, B=1, ... Z=25, a=26, ... z=51, 0=52, ... 9=61, +=62, /=63).

Let us encode the string Hi! as an example:

Text:    H         i         !
ASCII:   72        105       33
Binary:  01001000  01101001  00100001
6-bit:   010010  000110  100100  100001
Index:   18      6       36      33
Base64:  S       G       k       h

So Hi! becomes SGkh in Base64.

Padding with =

Since Base64 works in groups of 3 bytes, what happens when the input length is not a multiple of 3? This is where padding comes in. The = character is appended to fill the gap:

  • 1 byte remaining: The byte is padded with zeros to fill two 6-bit groups, resulting in 2 Base64 characters followed by ==.
  • 2 bytes remaining: The bytes are padded with zeros to fill three 6-bit groups, resulting in 3 Base64 characters followed by =.
  • 0 bytes remaining: No padding needed — the output length is an exact multiple of 4.
"A"     -> "QQ=="    (1 byte  -> 2 chars + ==)
"Hi"    -> "SGk="    (2 bytes -> 3 chars + =)
"Hi!"   -> "SGkh"    (3 bytes -> 4 chars, no padding)
"Hello" -> "SGVsbG8=" (5 bytes -> 7 chars + =)

Base64URL Variant

Standard Base64 uses + and / which have special meanings in URLs and filenames. The Base64URL variant replaces them with - (minus) and _ (underscore), and often omits the padding = characters. JWTs use this Base64URL encoding.

Common Use Cases for Base64

1. Data URIs (Embedding Images in HTML/CSS)

One of the most common uses of Base64 in web development is embedding small images directly in HTML or CSS using Data URIs. This eliminates an extra HTTP request for each image.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEU..." />

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

Tip: Only use Data URIs for small images (under 5KB). Base64 encoding increases the data size by approximately 33%, so large images should still be served as separate files.

2. JSON Web Tokens (JWT)

JWTs use Base64URL encoding for their three parts (header, payload, and signature). This ensures the token can be safely transmitted in HTTP headers and URL query parameters without any special character issues.

3. API Authentication (Basic Auth)

HTTP Basic Authentication encodes the username:password string in Base64 and sends it in the Authorization header:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
// "username:password" encoded in Base64

Security Warning: Basic Auth only Base64-encodes the credentials — it does not encrypt them. Always use HTTPS when transmitting Basic Auth headers.

4. Email Attachments (MIME)

Email protocols (SMTP) were originally designed for 7-bit ASCII text. Binary attachments like images, PDFs, and documents are Base64-encoded so they can travel through the email system without corruption. The MIME standard (Multipurpose Internet Mail Extensions) specifies how this encoding is applied.

5. Storing Binary Data in JSON/XML

JSON and XML are text-based formats that cannot natively represent binary data. Base64 provides a reliable way to embed binary content (such as cryptographic keys, certificates, or small files) within these text formats.

Base64 in Code: JavaScript, Python, and CLI

JavaScript (Browser and Node.js)

// Browser - encode and decode strings
const encoded = btoa("Hello, World!");
// "SGVsbG8sIFdvcmxkIQ=="

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

// Handle Unicode strings (btoa only supports Latin1)
const unicodeEncode = (str) =>
  btoa(encodeURIComponent(str).replace(
    /%([0-9A-F]{2})/g,
    (_, p1) => String.fromCharCode(parseInt(p1, 16))
  ));

// Node.js - using Buffer
const buf = Buffer.from("Hello, World!");
const b64 = buf.toString("base64");
// "SGVsbG8sIFdvcmxkIQ=="

const original = Buffer.from(b64, "base64").toString("utf-8");
// "Hello, World!"

// Node.js - encode a file
const fs = require("fs");
const fileB64 = fs.readFileSync("image.png").toString("base64");

Python

import base64

# Encode a string
encoded = base64.b64encode(b"Hello, World!").decode("ascii")
# "SGVsbG8sIFdvcmxkIQ=="

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

# Base64URL encoding (used in JWTs)
url_encoded = base64.urlsafe_b64encode(b"Hello, World!").decode("ascii")
# "SGVsbG8sIFdvcmxkIQ=="

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

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 image.png > image_b64.txt

# Decode a file
base64 --decode image_b64.txt > image_restored.png

# macOS uses -D instead of --decode
echo "SGVsbG8=" | base64 -D

Base64 vs Encryption: Understanding the Difference

A common misconception is that Base64 provides some form of security. It does not. Here is a clear comparison:

AspectBase64 EncodingEncryption
PurposeData representationData protection
Reversible?Yes, by anyoneOnly with the correct key
Key required?NoYes
SecurityNoneConfidentiality guarantee
Use caseData transport / embeddingProtecting sensitive data

Never rely on Base64 encoding to hide sensitive information. If you need to protect data, use proper encryption algorithms like AES-256-GCM or RSA. Base64 is a format, not a security measure.

Performance Considerations and Best Practices

  • 33% size overhead. Base64 encoding increases data size by approximately one third. Three bytes of binary data become four bytes of Base64 text. Factor this into bandwidth and storage calculations.
  • Do not Base64-encode large files. For images larger than a few kilobytes, serve them as separate files and let the browser cache them. Inlining large Base64 strings bloats your HTML/CSS and defeats caching.
  • Use streaming for large data. When encoding or decoding large files in Node.js or Python, use streaming APIs to avoid loading the entire file into memory at once.
  • Choose the right variant. Use standard Base64 for general purposes and Base64URL when the encoded string will appear in URLs, filenames, or JWTs.
  • Validate before decoding. Always validate that a string is valid Base64 before attempting to decode it. Invalid characters or incorrect padding can cause errors or unexpected behavior.
  • Consider Content-Transfer-Encoding. When sending Base64 data in HTTP responses, set appropriate headers. For binary content, it is often better to use actual binary transfer rather than Base64-encoding it.

Related Tools

Work with Base64 and related encodings using these free online tools:

Try These Tools

Need a form backend for your project?

FormCatch handles form submissions so you don't have to. Free tier included.

Try FormCatch Free →
Support us$3$5$10