Base64 Encoding Explained

Last updated:

Base64 converts any binary data into a 64-character ASCII alphabet so it can travel safely over text-only channels such as HTTP headers, JSON fields, and email. Every 3 input bytes expand to exactly 4 Base64 characters — a fixed ~33% size overhead, so a 1 MB image becomes ~1.37 MB encoded. Base64url is a 2-character variant that swaps + - and / _, used in all 3 parts of a JWT. This guide covers 5 topics: how the 6-bit encoding algorithm works, Base64 vs Base64url differences, encoding and decoding in browsers (btoa() / atob()), Node.js 16+ Buffer API, and data URIs for embedding images inline without an extra HTTP request.

What is Base64?

Base64 is an encoding scheme that converts binary data into a string of 64 printable ASCII characters. It is not encryption — it is purely a way to represent arbitrary bytes as text.

The 64 characters are: A–Z (26), a–z (26), 0–9 (10), plus + and / (2), with = used for padding. Every possible byte value maps to a combination of these characters.

Why does Base64 exist?

Many protocols were designed to handle text, not arbitrary binary data. Email (SMTP), HTTP headers, and URLs all have restrictions on which byte values are safe to transmit.

If you need to embed a PNG image in an email or an HTTP header, you can't just include raw bytes — certain byte values would be misinterpreted as control characters. Base64 solves this by mapping all binary data to a safe subset of ASCII that travels through text-based protocols without corruption.

How encoding works

Base64 works by grouping the input bytes into 3-byte (24-bit) chunks, then splitting each chunk into four 6-bit groups. Each 6-bit group (values 0–63) maps to one character in the alphabet.

Input:  "Man"
Bytes:  77  97  110
Binary: 01001101 01100001 01101110

Split into 6-bit groups:
010011  010110  000101  101110
  19      22      5      46

Base64 alphabet lookup:
  T       W       F      u

Encoded: "TWFu"

If the input length is not a multiple of 3, the output is padded with = or ==to keep the output length a multiple of 4.

Base64 variants

Three variants are in common use today. They share the same 6-bit grouping algorithm but use different alphabets for the two non-alphanumeric characters and different padding rules.

VariantChar 62Char 63PaddingWhere used
Standard (RFC 4648 §4)+/= requiredEmail, generic encoding, btoa in JS
URL-safe (RFC 4648 §5)-_= optionalJWT, OAuth tokens, URL parameters
MIME (RFC 2045)+/= required, line-wrap at 76 charsEmail attachments, S/MIME

Base64 in practice: where you encounter it

JWTs

Each of the three parts of a JSON Web Token (header, payload, signature) is Base64url-encoded. Base64url is a variant that uses - instead of + and _instead of /, making it safe in URLs and HTTP headers without percent-encoding.

// JWT header (base64url-encoded)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

// Decoded:
{ "alg": "HS256", "typ": "JWT" }

Data URIs

You can embed an image directly in HTML or CSS by encoding it as Base64 and using a data URI:

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

Useful for small icons you want to inline to avoid an extra HTTP request. Not practical for large images — Base64 increases size by about 33%.

HTTP Basic Authentication

The Authorization: Basic header sends credentials as Base64:

// credentials: "alice:secretpassword"
// base64 encoded:
Authorization: Basic YWxpY2U6c2VjcmV0cGFzc3dvcmQ=

This is not secure on its own — Base64 is trivially reversible. Basic Auth only makes sense over HTTPS.

API request/response payloads

Some APIs encode binary fields (images, PDFs, file contents) as Base64 strings within JSON payloads, since JSON itself has no binary type.

{
  "filename": "invoice.pdf",
  "content": "JVBERi0xLjQKJeLjz9..."
}

Encoding and decoding in JavaScript

The browser and Node.js both provide btoa (binary to ASCII) and atob (ASCII to binary):

// Encode
btoa('Hello, world!')  // → "SGVsbG8sIHdvcmxkIQ=="

// Decode
atob('SGVsbG8sIHdvcmxkIQ==')  // → "Hello, world!"

For Unicode strings, you need an extra step because btoa only handles Latin-1:

// Encode Unicode string to Base64
function encodeBase64(str) {
  return btoa(unescape(encodeURIComponent(str)))
}

// Decode Base64 to Unicode string
function decodeBase64(str) {
  return decodeURIComponent(escape(atob(str)))
}

encodeBase64('こんにちは')  // → "44GT44KT44Gr44Gh44Gv"
decodeBase64('44GT44KT44Gr44Gh44Gv')  // → "こんにちは"

Base64url variant

When encoding for use in URLs (like JWTs), replace the URL-unsafe characters and strip padding:

function toBase64url(base64) {
  return base64.replace(/+/g, '-').replace(///g, '_').replace(/=/g, '')
}

function fromBase64url(base64url) {
  const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/')
  return base64 + '='.repeat((4 - base64.length % 4) % 4)
}

Size overhead

Base64 encoding increases data size by approximately 33%. Every 3 bytes of input becomes 4 characters of output. This is the cost of making binary safe for text protocols.

Original:  100 bytes  → Base64: ~136 characters
Original:  1 KB       → Base64: ~1.37 KB
Original:  1 MB image → Base64: ~1.37 MB

This overhead is acceptable for small values (tokens, icons, credentials) but significant for large binary files. If you're storing or transferring large binary data, use a binary protocol or multipart form data instead.

Encode or decode Base64 now

Paste any text or Base64 string into Jsonic's Base64 tool to instantly encode or decode it. Handles Unicode correctly. Runs entirely in your browser — nothing is uploaded.

Open Base64 Tool

Frequently asked questions

What is Base64 encoding used for?

Base64 is used to transmit binary data through text-only channels: data URIs in HTML/CSS, JWT header and payload encoding, HTTP Basic Auth credentials, binary fields in JSON API responses, and email attachments. It converts binary to safe ASCII text.

Why does Base64 add padding characters?

Base64 encodes 3 bytes as 4 characters. When input length is not a multiple of 3, = characters pad the output to a multiple of 4. One = means the last group had 2 bytes; two == means it had 1 byte. Base64URL often omits padding.

What is the difference between Base64 and Base64URL?

Standard Base64 uses + and /, which have special meaning in URLs. Base64URL replaces them with - and _, making the output URL-safe. JWTs use Base64URL. Base64URL also typically omits = padding.

How much does Base64 increase data size?

Base64 increases size by approximately 33% — every 3 bytes become 4 characters. A 1 MB file becomes ~1.37 MB. This is acceptable for tokens and icons, but significant for large binary files where multipart/form-data is a better alternative.

Is Base64 encryption?

No. Base64 provides zero security or confidentiality. It is trivially reversible by anyone without any key. HTTP Basic Auth credentials in Base64 are not protected — HTTPS encrypts the transport, not Base64. Use actual encryption (AES, RSA) for security.

How do I decode a Base64 string?

JavaScript browser: atob("SGVsbG8="). Node.js: Buffer.from("SGVsbG8=", "base64").toString("utf8"). Python: base64.b64decode("SGVsbG8=").decode("utf-8"). Command line: echo "SGVsbG8=" | base64 -d.

Further reading and primary sources