Encoding

What is Base64 Encoding? A Complete Guide with Examples

2026-05-03 · 9 min read · Encode Base64 free →

If you have worked with APIs, email attachments, data URLs, or authentication tokens, you have used Base64 whether you realised it or not. It is one of the most widely used encoding schemes in computing, yet it is also one of the most misunderstood. Developers regularly confuse it with encryption, misapply it to problems it does not solve, or use it where it is not needed. This guide explains exactly what Base64 is, how it works mathematically, where it is legitimately useful, and where you should not use it.

What is Base64?

Base64 is an encoding scheme that converts binary data into a string of printable ASCII characters. It uses an alphabet of 64 characters: uppercase letters A–Z (26), lowercase letters a–z (26), digits 0–9 (10), and the symbols + and / (2). A 65th character, =, is used for padding.

The name comes directly from this alphabet size: base 64. Just as decimal numbers use base 10 (10 digits) and hexadecimal uses base 16 (16 characters), Base64 uses 64 characters as its "digits."

The key property of Base64 is that every character in its output is a safe, printable ASCII character. This makes Base64-encoded data safe to put anywhere that text is expected: email bodies, JSON strings, URLs, HTML attributes, XML documents, and HTTP headers.

How Base64 Encoding Works

Base64 converts every 3 bytes of binary data into 4 ASCII characters. Here is the step-by-step process:

Take 3 bytes of input data (24 bits total). Split those 24 bits into four groups of 6 bits each. Use each 6-bit group as an index into the 64-character alphabet. The result is 4 ASCII characters that represent those 3 original bytes.

Since 2⁶ = 64, a 6-bit group can represent any index from 0 to 63 — exactly the size of the Base64 alphabet. This is why exactly 64 characters were chosen: they map perfectly to 6-bit groups.

If the input is not divisible by 3, padding is added. 1 remaining byte becomes 2 output characters plus ==. 2 remaining bytes become 3 output characters plus =. The = padding characters tell the decoder how many bytes were in the final group.

A concrete example

Input string:  "Man"
ASCII bytes:   77  97  110
Binary:        01001101 01100001 01101110
6-bit groups:  010011 010110 000101 101110
Base64 index:  19     22     5      46
Base64 chars:  T      W      F      u
Output:        "TWFu"

This 3:4 ratio means Base64 output is always 33% larger than the input. Three bytes in, four characters out. This overhead is the trade-off for making binary data safe to transmit as text.

Base64 vs Encryption: A Critical Distinction

Base64 is not encryption. It provides zero security. Anyone who sees a Base64-encoded string can decode it instantly — the algorithm is public, reversible, and requires no key. Encoding password123 as cGFzc3dvcmQxMjM= hides nothing; it is trivially decoded by anyone.

Do not store passwords or secrets in Base64. Base64 is encoding, not encryption. Use bcrypt or Argon2 for passwords, and AES-256 or ChaCha20 for data that needs genuine confidentiality.

The confusion arises because Base64 strings look scrambled. They are not — they are simply reformatted. Think of it like Pig Latin: the words look different but there is no secret, and anyone who knows the rules can decode them immediately.

Where Base64 is Genuinely Useful

Embedding images in HTML and CSS (Data URLs)

You can embed images directly into HTML or CSS without a separate file request using a data URL. The image binary is Base64-encoded and embedded inline. This eliminates one HTTP request per image, which matters most for small icons and UI elements.


<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="1x1 pixel">

/* Same technique in CSS */
.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==");
}

Transmitting binary data through text-only channels

Email was originally designed for 7-bit ASCII text. MIME attachments use Base64 to encode binary files (PDFs, images, executables) into text that email servers can safely relay. This is why email attachments are Base64-encoded under the hood.

Similarly, when you send binary data in a JSON API request (a file upload, an image, a certificate), you often Base64-encode it so it fits safely in a JSON string field. JSON strings are Unicode text — they cannot directly contain arbitrary binary bytes.

HTTP Basic Authentication

HTTP Basic Auth sends credentials as username:password encoded in Base64 in the Authorization header. This is purely for safe transport in an HTTP header — it is not encryption. HTTPS is what provides the security; the Base64 is just formatting.

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
# Decodes to: username:password

JWT Tokens

JSON Web Tokens (JWTs) use Base64URL encoding (a variant using - and _ instead of + and / so the token is URL-safe). A JWT has three Base64URL-encoded sections separated by dots: header, payload, and signature. The header and payload are just Base64-encoded JSON — anyone can decode them. The signature is what provides security — it verifies the token was not tampered with.

Encoding binary data in XML and JSON APIs

Neither XML nor JSON has a native binary data type. When an API needs to return binary data — a thumbnail, a PDF, a cryptographic key — it Base64-encodes the binary into a string field. The receiver decodes it back to binary. This is standard practice in REST APIs, GraphQL, and SOAP web services.

Base64 Variants You Will Encounter

VariantChars 62–63PaddingUsed in
Standard Base64+ /= requiredEmail (MIME), general purpose
Base64URL- _= optionalJWTs, URLs, filenames
Base64 MIME+ /= requiredEmail MIME, line breaks at 76 chars

The URL-safe variant (Base64URL) replaces + with - and / with _ because + and / have special meanings in URLs (space and path separator respectively). Always use Base64URL when the encoded string will appear in a URL or filename.

Encoding and Decoding Base64 in Code

JavaScript (Browser)

// Encode a string to Base64
const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="

// Decode Base64 to a string
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"

// For binary data (files, images), use FileReader or Buffer in Node.js
// btoa/atob only work reliably with ASCII strings

// Node.js (Buffer approach — handles all binary data)
const encoded = Buffer.from("Hello, World!").toString("base64");
const decoded = Buffer.from(encoded, "base64").toString("utf8");

Python

import base64

# Encode bytes to Base64 string
data = b"Hello, World!"
encoded = base64.b64encode(data)
print(encoded)  # b'SGVsbG8sIFdvcmxkIQ=='

# Decode Base64 string to bytes
decoded = base64.b64decode(b"SGVsbG8sIFdvcmxkIQ==")
print(decoded)  # b'Hello, World!'

# URL-safe variant (for JWTs, URLs)
encoded_url = base64.urlsafe_b64encode(data)
decoded_url = base64.urlsafe_b64decode(encoded_url)

Common Mistakes with Base64

Using it for security: Already covered — Base64 is not encryption. Do not use it to "protect" sensitive data.

Overusing it for large files: Base64 increases size by 33%. Embedding a 1MB image as a Base64 data URL in your HTML adds 1.33MB to every page load. Use it for small assets (icons under 10KB); serve large files as separate HTTP resources with proper caching headers.

Mixing standard and URL-safe variants: Standard Base64 with + and / will break in URLs. Always use Base64URL when the output goes into a URL. A common symptom: a Base64 value that works in a tool but produces an error when passed as a query parameter — almost always a + being interpreted as a space.

Forgetting padding: Some systems strip = padding characters. A valid Base64 string must have a length divisible by 4 (padded with = as needed). If your decoder fails with an invalid length error, try adding = padding: s += '=' * (4 - len(s) % 4).

Try encoding and decoding in your browser right now with ToolPry's Base64 Encoder — it handles both standard and URL-safe variants, works with files, and processes everything client-side.

Detecting and Decoding Base64 in the Wild

You will often encounter Base64-encoded data without an obvious label. Recognising it on sight saves debugging time. Base64 strings have a few telltale characteristics: they only contain letters, digits, +, /, and = (or -, _ for URL-safe). Their length is always divisible by 4 (or would be, with padding). They typically end with one or two = characters. And they look like random text — a mix of upper and lowercase letters and digits with no obvious word patterns.

JWTs are a particularly common form of Base64 in the wild. A JWT looks like three Base64URL-encoded strings separated by dots: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMSJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c. The first two parts (header and payload) are just Base64-decoded JSON — you can decode them instantly to see the token's claims without any library.

Frequently Asked Questions

Is Base64 the same as encryption?

No — this is the most important thing to understand about Base64. Encoding and encryption are fundamentally different. Encoding transforms data into a different representation using a public algorithm that anyone can reverse. Encryption transforms data using a secret key — without the key, the data cannot be recovered. Base64 has no key and no secret. Anyone who sees a Base64 string can decode it immediately. Never use Base64 to protect sensitive data.

Why does Base64 output end with = or ==?

Base64 converts 3 bytes into 4 characters. If your input is not divisible by 3, padding is required. One leftover byte produces two output characters plus ==. Two leftover bytes produce three output characters plus =. The equals signs are padding to make the output length a multiple of 4, which makes it easier for decoders to determine where the last group ends. Some implementations omit padding — if you receive a Base64 string with a length not divisible by 4, add the missing = characters before decoding.

What is the size overhead of Base64?

Base64 produces output that is exactly 4/3 times the size of the input — a 33% overhead. A 1MB file encoded in Base64 becomes approximately 1.33MB. This overhead is fixed and predictable regardless of the content. For small data (icons, short tokens), the overhead is negligible. For large files, it can be significant — a 100MB file becomes 133MB when Base64-encoded, which is why Base64 is not used for transferring large binary files over HTTP where multipart form data is more efficient.

When should I use URL-safe Base64?

Use URL-safe Base64 (Base64URL) whenever the encoded string will appear in a URL, filename, or any context where + or / have special meaning. Standard Base64 uses + (which means space in query strings) and / (which means path separator in URLs). Base64URL replaces them with - and _, which have no special URL meaning. JWT tokens, for example, use Base64URL because they often appear in URL query parameters and HTTP headers.

Can Base64 encode any type of data?

Yes. Base64 operates on raw bytes, so it can encode any binary data regardless of format: images, PDFs, audio files, executables, text in any encoding, compressed archives, or arbitrary binary data. The encoder does not care about the content or format of the bytes — it simply converts groups of 3 bytes into 4 characters. This universality is what makes Base64 useful as a general-purpose binary-to-text conversion mechanism.

How do I decode a Base64 string to find out what it contains?

Use ToolPry's Base64 Decoder — paste the string and the decoded output appears instantly. For text content, you will see the original text directly. For binary content (images, files), the decoded bytes need to be interpreted by the appropriate viewer. If you are trying to decode a JWT specifically, tools like jwt.io show the decoded header and payload (the Base64URL-decoded JSON) without requiring you to decode manually.