正在加载,请稍候…

Base64 Encoding and Decoding: A Practical Developer Guide

Learn what Base64 is, how it works, common use cases from data URLs to JWT, and how to encode and decode Base64 in JavaScript, Python, and other languages.

What Is Base64?

Base64 is a binary-to-text encoding scheme that represents binary data using only 64 printable ASCII characters: A-Z, a-z, 0-9, +, and / (plus = for padding). The name "Base64" comes from this 64-character alphabet.

It was designed for a specific problem: some systems (email protocols, XML documents, URLs) were designed to handle text, not raw binary. Base64 lets you embed binary data — images, files, encrypted bytes, cryptographic signatures — in text-only contexts.

Base64 is not encryption. It has no key and provides no security. Decoding is trivial and reversible by anyone. Its purpose is encoding for compatibility, not secrecy.

How Base64 Works

Base64 works by:

  1. Taking input bytes in groups of 3 (24 bits)
  2. Splitting each 24-bit group into four 6-bit chunks
  3. Looking up each 6-bit value in the Base64 alphabet (0–63 → A–Z, a–z, 0–9, +, /)
  4. If the input isn't a multiple of 3 bytes, adding = padding characters

Example: encoding "Man"

Input:    M        a        n
ASCII:    77       97       110
Bits:     01001101 01100001 01101110

Group of 24 bits: 010011 010110 000101 101110
Lookup:           T      W      F      u
Output:   TWFu

Size increase: Base64 output is always 4/3 the size of the input (plus padding). A 3-byte input becomes 4 characters. A 1 MB file becomes ~1.37 MB Base64-encoded.

Padding

If the input length isn't a multiple of 3:

  • 1 remaining byte → 2 Base64 characters + ==
  • 2 remaining bytes → 3 Base64 characters + =
"M"  → TWO= (1 byte input → 4 chars with == padding)
"Ma" → TWE= (2 bytes input → 4 chars with = padding)
"Man"→ TWFu (3 bytes input → 4 chars, no padding)

URL-Safe Base64

Standard Base64 uses + and /, which have special meanings in URLs. Base64url replaces:

  • +-
  • /_
  • Often omits padding = (since %3D in URLs is ugly)

Used in: JWTs, OAuth tokens, many web APIs.

Encoding and Decoding in Code

JavaScript (Browser)

// Browser built-ins: btoa (binary to ASCII) and atob (ASCII to binary)

// Encode string to Base64
const encoded = btoa('Hello, World!');
// => 'SGVsbG8sIFdvcmxkIQ=='

// Decode Base64 to string
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
// => 'Hello, World!'

// ⚠️ btoa/atob only work with Latin-1 characters.
// For Unicode strings, encode to UTF-8 bytes first:
function toBase64(str) {
  return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
    (_, p1) => String.fromCharCode(parseInt(p1, 16))
  ));
}

function fromBase64(b64) {
  return decodeURIComponent(atob(b64).split('').map(
    c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
  ).join(''));
}

// Or use the modern TextEncoder approach:
function toBase64Modern(str) {
  const bytes = new TextEncoder().encode(str);
  let binary = '';
  for (const b of bytes) binary += String.fromCharCode(b);
  return btoa(binary);
}

JavaScript (Node.js)

// Node.js — Buffer
const text = 'Hello, World!';

// Encode
const encoded = Buffer.from(text).toString('base64');
// => 'SGVsbG8sIFdvcmxkIQ=='

// Base64url (no padding, URL-safe chars)
const encodedUrl = Buffer.from(text).toString('base64url');

// Decode
const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8');
// => 'Hello, World!'

// Encode a file
const { readFileSync } = require('fs');
const fileBase64 = readFileSync('/path/to/image.png').toString('base64');

Python

import base64

# Encode bytes
encoded = base64.b64encode(b'Hello, World!')
print(encoded)         # b'SGVsbG8sIFdvcmxkIQ=='
print(encoded.decode())  # 'SGVsbG8sIFdvcmxkIQ=='

# Decode
decoded = base64.b64decode('SGVsbG8sIFdvcmxkIQ==')
print(decoded)  # b'Hello, World!'

# URL-safe Base64
url_encoded = base64.urlsafe_b64encode(b'binary data here')
url_decoded = base64.urlsafe_b64decode(url_encoded)

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

Go

import "encoding/base64"

// Encode
encoded := base64.StdEncoding.EncodeToString([]byte("Hello, World!"))
// => "SGVsbG8sIFdvcmxkIQ=="

// URL-safe (no padding)
encodedUrl := base64.RawURLEncoding.EncodeToString([]byte("Hello, World!"))

// Decode
decoded, err := base64.StdEncoding.DecodeString("SGVsbG8sIFdvcmxkIQ==")

Common Use Cases

1. Data URLs (Inline Images in HTML/CSS)

Embed images directly in HTML or CSS without separate HTTP requests:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />
.icon {
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL...');
}

Good for small icons and critical images that shouldn't require separate requests. Avoid for large images — Base64 increases size by 33% and prevents caching.

2. JWT (JSON Web Tokens)

A JWT is three Base64url-encoded parts separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
^header^                              ^payload^                        ^signature^

Decoding the header: atob('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'){"alg":"HS256","typ":"JWT"}

3. Email Attachments (MIME)

SMTP was designed for ASCII text. Email clients encode attachments as Base64 in MIME parts:

Content-Type: image/jpeg
Content-Transfer-Encoding: base64

/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsL...

4. Storing Binary in JSON

JSON doesn't support binary. When an API needs to return binary data (e.g., a thumbnail, an encrypted blob) inside a JSON response, Base64 encoding is the standard approach:

{
  "id": "file-123",
  "thumbnail": "data:image/webp;base64,UklGRiQAAABXRUJQVlA4...",
  "encrypted_key": "c2VjcmV0a2V5..."
}

5. Basic Authentication Header

HTTP Basic Auth sends credentials as Base64(username:password):

Authorization: Basic dXNlcjpwYXNzd29yZA==

atob('dXNlcjpwYXNzd29yZA==')user:password

This is Base64, not encryption — always use HTTPS with Basic Auth. The encoding only prevents casual observation, not interception.

6. Cryptographic Keys and Certificates

PEM files (the ones that start with -----BEGIN CERTIFICATE-----) contain Base64-encoded DER binary data:

-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUMTIzNDU2Nzg5MEFCQ0RFRjAxMjM0NTY3ODkwMTIz...
-----END CERTIFICATE-----

Common Mistakes

Encoding instead of encrypting: Base64 is trivially reversible. Never "protect" sensitive data with just Base64.

Not handling Unicode in browsers: btoa() throws on non-Latin-1 characters. Use TextEncoder or the percent-encoding approach shown above.

Forgetting padding when decoding: Some systems strip the = padding. When decoding, you may need to add it back: b64 + '='.repeat((4 - b64.length % 4) % 4).

Using wrong variant: Standard Base64 (+, /) vs Base64url (-, _). Using the wrong one causes decode failures.

→ Encode and decode Base64 strings instantly with the Base64 String Converter.