If you've worked with web APIs, email systems, or embedded images in CSS, you've almost certainly encountered Base64 encoding โ€” perhaps without fully understanding what it is. Strings like SGVsbG8sIFdvcmxkIQ== or seeing data:image/png;base64,iVBORw0KGgo... in your code are Base64 in action.

This guide explains Base64 in plain terms: what it is, the math behind it, and when (and when not) to use it.

What Is Base64?

Base64 is an encoding scheme that converts binary data (bytes) into a string of ASCII characters. The name "Base64" refers to the fact that the encoding uses a 64-character alphabet to represent binary data.

Those 64 characters are:

  • Letters Aโ€“Z (26 characters)
  • Letters aโ€“z (26 characters)
  • Digits 0โ€“9 (10 characters)
  • The characters + and / (2 characters)
  • The = sign is used for padding

The fundamental purpose of Base64 is to represent arbitrary binary data using only a safe subset of ASCII characters. This matters because many text-based systems โ€” email protocols, URLs, HTML attributes, JSON โ€” were designed to handle text, not arbitrary binary data. Base64 bridges that gap.

Why Was Base64 Invented?

The origins of Base64 go back to email. Early email systems like SMTP (Simple Mail Transfer Protocol) were designed to transmit only 7-bit ASCII text. If you tried to attach a binary file (like an image or an executable), the bytes could contain values that the email server would misinterpret as control characters, corrupting the data.

Base64 solved this by encoding binary data into safe ASCII text. The MIME (Multipurpose Internet Mail Extensions) standard, developed in the early 1990s, used Base64 as one of its core encoding mechanisms โ€” which is why you can attach files to emails today.

How Does Base64 Encoding Work?

The algorithm is elegant but requires some explanation. Let's walk through it step by step:

Step 1: Convert to Binary

Take the input text (or binary data) and convert each character to its binary representation. Each byte is 8 bits.

For example, the text "Hi!" in ASCII/UTF-8:

  • H = 72 = 01001000
  • i = 105 = 01101001
  • ! = 33 = 00100001

Combined: 010010000110100100100001 (24 bits)

Step 2: Split into 6-Bit Groups

Base64 works in 6-bit chunks (because 2^6 = 64, which is why we have 64 characters). Split the 24 bits into groups of 6:

  • 010010 = 18
  • 000110 = 6
  • 100100 = 36
  • 100001 = 33

Step 3: Map to Base64 Characters

Each 6-bit value maps to a character in the Base64 alphabet:

  • 18 โ†’ S
  • 6 โ†’ G
  • 36 โ†’ k
  • 33 โ†’ h

Result: SGkh

And indeed, encoding "Hi!" in Base64 gives you SGkh. You can verify this with any Base64 encoder tool.

Padding with =

Base64 works in groups of 3 bytes (24 bits), which produce 4 Base64 characters. If the input isn't a multiple of 3 bytes, the output is padded with = signs:

  • 1 remaining byte โ†’ 2 Base64 characters + ==
  • 2 remaining bytes โ†’ 3 Base64 characters + =

This is why you often see Base64 strings ending in = or ==.

Base64 Is Encoding, Not Encryption

This is critical to understand: Base64 is not a security mechanism. It does not encrypt data. Anyone who receives a Base64-encoded string can instantly decode it using any Base64 decoder tool โ€” no key, no password required.

Base64 is purely a data format conversion. It changes the representation of data without protecting it. If you Base64-encode a password and transmit it, the password is just as exposed as if you'd sent it in plain text โ€” perhaps more so, because developers might mistakenly assume encoding means security.

Never use Base64 as a security measure. Use proper encryption (AES, RSA, etc.) or hashing (bcrypt, SHA-256) when security is required.

Real-World Use Cases for Base64

1. Embedding Images in HTML and CSS

Instead of linking to an image file, you can embed the image directly in your HTML or CSS using a Data URI:

background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...");

This is useful for:

  • Small icons that are critical to render (no separate HTTP request needed)
  • Inlining images in email templates (which don't reliably load external images)
  • Generating images dynamically and displaying them without saving to disk

The downside: Base64-encoded data is ~33% larger than the original binary, so this isn't suitable for large images.

2. HTTP Basic Authentication

The HTTP Basic Authentication scheme transmits credentials by Base64-encoding the username and password in the Authorization header:

Authorization: Basic dXNlcjpwYXNzd29yZA==

This is "user:password" Base64-encoded. Note again that this is not encrypted โ€” Basic Auth only makes sense over HTTPS, where the entire HTTP header is encrypted by TLS.

3. JSON Web Tokens (JWT)

JSON Web Tokens, widely used for authentication in web APIs, consist of three Base64-encoded sections separated by dots:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

You can decode the header and payload sections of a JWT directly โ€” they're just Base64-encoded JSON. Only the signature requires the secret key to verify.

4. Email Attachments (MIME)

As mentioned earlier, email attachments are Base64-encoded in the MIME format. When you attach a PDF to an email, your email client converts the binary PDF file to a Base64 string that can be safely transmitted through text-based email systems.

5. Storing Binary Data in Text-Only Systems

Databases, configuration files, and APIs that only handle text can store binary data (images, certificates, documents) as Base64 strings. This is common in:

  • Storing user avatars in JSON responses from REST APIs
  • Including SSL/TLS certificates in YAML configuration files
  • Passing binary data in URL query parameters (though URL-safe Base64 is used in this case)

URL-Safe Base64

Standard Base64 uses + and / characters, which have special meaning in URLs (+ means space, / separates path segments). URL-safe Base64 replaces these characters:

  • + โ†’ - (hyphen)
  • / โ†’ _ (underscore)

URL-safe Base64 is commonly used in JWT tokens, Google's APIs, and anywhere Base64 data needs to appear in a URL without encoding issues.

How Much Bigger Is Base64?

Base64 encoding adds approximately 33% overhead to the size of the original data. This is because every 3 bytes (24 bits) of input becomes 4 characters (32 bits) of Base64 output.

For small files (icons, simple images), this overhead is acceptable. For large files (high-resolution images, videos, documents), the 33% size increase becomes significant. In these cases, it's better to link to the file rather than embed it as Base64.

Decoding Base64

Decoding is simply the reverse process: take the Base64 characters, look up their 6-bit values, concatenate all the bits, and split them into 8-bit bytes.

Every modern programming language has built-in Base64 encode/decode functions:

  • JavaScript: btoa(str) / atob(str)
  • Python: base64.b64encode() / base64.b64decode()
  • PHP: base64_encode() / base64_decode()
  • Java: Base64.getEncoder().encodeToString()
  • Command line: echo "text" | base64

Common Mistakes with Base64

  • Treating it as encryption. It's not. Anyone can decode it.
  • Using it for large files. The 33% size overhead makes it impractical for images over ~10KB embedded in HTML/CSS.
  • Forgetting padding. Some implementations require the = padding; others allow omitting it. If you see "Invalid Base64" errors, check for missing padding.
  • Mixing up standard and URL-safe Base64. If your Base64 string will appear in a URL, use URL-safe Base64 (- and _ instead of + and /).

Base64 is a fundamental tool in any developer's toolkit. Once you understand what it does and why, you'll recognize it everywhere โ€” in JWTs, API responses, email headers, and CSS files โ€” and know exactly how to work with it.