Toolypet
Back to Blog
Dev

Complete Guide to Base64 Encoding: From Principles to Applications

Learn how Base64 encoding works and practical ways to use it in web development.

Toolypet Team6 min read
Complete Guide to Base64 Encoding: From Principles to Applications

Why Was Base64 Created?

To understand the origins of Base64, we need to go back to email systems in the 1970s. At the time, the email protocol SMTP could only transmit 7-bit ASCII characters. Only English alphabets, numbers, and basic symbols were supported - binary files like images or documents couldn't be transmitted, nor could multi-byte characters like Korean or Chinese.

To solve this problem, the MIME (Multipurpose Internet Mail Extensions) standard was developed, and one of its core technologies is Base64. Base64 converts any binary data into a safe ASCII string, enabling file transmission even through systems that can only handle text.

Today, Base64 is still widely used. You'll encounter it in email attachments, inline images on web pages, API authentication, JWT tokens, and many other places. It's fundamental knowledge that every web developer must understand.

The Core Principle: 64 Safe Characters

The name Base64 comes from using 64 characters. These 64 characters were carefully selected to be safely processed by virtually all systems worldwide:

A-Z (26) + a-z (26) + 0-9 (10) + + / (2) = 64 characters

Additionally, the = character is used for padding. Why 64? Because 64 is 2^6, one Base64 character can be represented with 6 bits. The relationship between bytes (8 bits), the unit computers use to process data, and 6 bits is the heart of the Base64 algorithm.

The Encoding Process: Step by Step

Let's look at how Base64 encoding works using "Man" as an example.

Step 1: Convert each character to 8-bit binary

M -> 77  -> 01001101
a -> 97  -> 01100001
n -> 110 -> 01101110

Step 2: Split 24 bits into four 6-bit groups

Dividing 24 bits (3 bytes) into 6-bit groups creates 4 groups. This is why Base64 increases data size by about 33% - 3 bytes of input become 4 characters (4 bytes) of output.

010011 | 010110 | 000101 | 101110

Step 3: Convert each 6-bit group to a Base64 character

010011 -> 19 -> T
010110 -> 22 -> W
000101 -> 5  -> F
101110 -> 46 -> u

Result: "Man" becomes "TWFu"

The Role of Padding (=)

What happens when input data isn't a multiple of 3 bytes? This is when the padding character = is used.

For example, encoding just "M" (1 byte):

  • Dividing 8 bits into 6-bit units leaves 2 bits remaining
  • Add 4 bits of 0 to create 2 Base64 characters
  • The remaining 2 positions are filled with =
"M" -> "TQ=="
"Ma" -> "TWE="
"Man" -> "TWFu"

Padding allows the exact length of original data to be known during decoding. However, padding is sometimes omitted when used in URLs.

Practical Uses in Web Development

1. Inlining Images with Data URIs

Data URIs allow images to be included directly in HTML or CSS without separate files.

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

Good use cases:

  • Small icons (1-2KB or less)
  • Images that aren't used repeatedly
  • When you need to reduce HTTP request count

Cases to avoid:

  • Large images (33% size increase becomes burdensome)
  • Same image used across multiple pages (caching not possible)
  • Images that change frequently

2. HTTP Basic Authentication

HTTP Basic authentication is one of the simplest authentication methods. It connects username and password with a colon, then encodes with Base64.

const username = 'admin';
const password = 'secret123';
const credentials = btoa(`${username}:${password}`);

fetch('https://api.example.com/data', {
  headers: {
    'Authorization': `Basic ${credentials}`
  }
});

The server decodes this header to extract authentication information. However, since Base64 is not encryption, it must always be used with HTTPS. If sent over HTTP, anyone can see the password.

3. JWT (JSON Web Token) Structure

JWT consists of three parts, each encoded with Base64URL:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.  // Header
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.  // Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c  // Signature

Base64URL is used in JWT because tokens can be passed as URL query parameters. Standard Base64's + and / have special meanings in URLs, so they're replaced with safe characters.

4. File Upload

When uploading files via Ajax, sometimes they're sent as Base64 strings instead of FormData:

const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const reader = new FileReader();

reader.onload = function(e) {
  const base64 = e.target.result;
  // Send to server
  fetch('/upload', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ file: base64 })
  });
};

reader.readAsDataURL(file);

This approach is convenient with JSON APIs, but since file size increases by 33%, it's not suitable for large files.

Usage by Programming Language

JavaScript (Browser)

// Encoding
const encoded = btoa('Hello World');  // "SGVsbG8gV29ybGQ="

// Decoding
const decoded = atob('SGVsbG8gV29ybGQ=');  // "Hello World"

Note: btoa() and atob() only support Latin characters. To handle Korean or emojis:

// UTF-8 encoding
function encodeUnicode(str) {
  return btoa(encodeURIComponent(str).replace(
    /%([0-9A-F]{2})/g,
    (_, p1) => String.fromCharCode('0x' + p1)
  ));
}

// UTF-8 decoding
function decodeUnicode(str) {
  return decodeURIComponent(
    atob(str).split('').map(c =>
      '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    ).join('')
  );
}

Node.js

// Encoding
const encoded = Buffer.from('Hello World').toString('base64');

// Decoding
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');

Python

import base64

# Encoding
encoded = base64.b64encode(b'Hello World').decode('utf-8')

# Decoding
decoded = base64.b64decode('SGVsbG8gV29ybGQ=').decode('utf-8')

# URL-safe Base64
url_safe = base64.urlsafe_b64encode(b'data').decode('utf-8')

Base64 vs Base64URL Comparison

PropertyBase64Base64URL
+ character+- (hyphen)
/ character/_ (underscore)
Padding =RequiredOptional (can be omitted)
Main usesEmail, general dataURLs, filenames, JWT

In URLs, + can be interpreted as a space, and / as a path separator. Base64URL prevents these issues.

Common Mistakes and Cautions

1. Confusing Base64 with encryption Base64 is encoding, not encryption. Anyone can easily decode it, so it should never be used to hide sensitive information. If security is needed, use actual encryption algorithms like AES.

2. Using Data URIs for large files Data URIs cannot be cached. Converting a 100KB image to Base64 makes it 133KB, and it's downloaded repeatedly every time the page loads. Separating it as an external file benefits from browser caching.

3. Ignoring line break characters Some Base64 implementations insert line breaks every 76 characters (MIME standard). If you don't remove line breaks before decoding, errors can occur.

4. Ignoring character encoding Encoding Korean directly with btoa() causes an error. You must first convert to UTF-8.

Toolypet Base64 Tool

Toolypet's Base64 encoder/decoder simplifies developer workflows:

  • Text conversion: Instantly convert plain text to Base64 or vice versa
  • File conversion: Convert images or documents to Base64 with drag and drop
  • Data URI generation: Automatically generate Data URIs with appropriate MIME types
  • Automatic UTF-8 handling: Perfect support for Korean, emojis, and other Unicode characters

When you need Base64 conversion during development, use it directly in your browser without installing separate libraries or writing code.

Base64EncodingBinary DataWeb Development