Skip to main content
Skip to main content
DevelopmentApril 8, 202613 min read

Base64 Encoding Explained: When and How

Base64 turns binary into safe ASCII text, but it is not encryption and it costs 33% size. A complete guide to how it works, the variants, and when each one fits.

Encode or decode Base64, Base64URL, Hex, and more with the Encoder/Decoder - locally in your browser.

What Base64 is

Base64 is a binary-to-text encoding that represents binary data using 64 printable ASCII characters: A-Z, a-z, 0-9, +, and /.

It exists because many channels - email, URLs, JSON, HTTP headers - were designed for text, and binary bytes can be mangled, split, or misinterpreted in transit.

Encoding is not encryption. Anyone can decode Base64 instantly; it changes representation, not confidentiality. Treat Base64 as packaging, and use real encryption whenever secrecy matters.

How the encoding works

Base64 processes input in groups of 3 bytes (24 bits). Each group becomes 4 characters of 6 bits each, mapped through the Base64 alphabet.

When the input length is not a multiple of 3, the final group is padded with one or two '=' characters so the output length stays a multiple of 4.

Every 3 bytes become 4 characters, which is why the encoded output is about 4/3 the size of the input - a 33% overhead before any line breaks or delimiters.

# 3 bytes: 0x4d 0x61 0x6e -> 'Man'
# 24 bits split into 6-bit groups:
# 010011 010110 000101 101110 -> T W F u
# JavaScript
globalThis.btoa('Man'); // 'TWFu'
globalThis.atob('TWFu'); // 'Man'

Standard Base64 vs Base64URL

The standard alphabet uses + and /, which are problematic in URLs: + is interpreted as a space in query strings, and / splits path segments.

Base64URL (RFC 4648 §5) replaces + with - and / with _, and omits padding in many implementations. It is the variant JWT segments use.

Mixing the two is a classic integration bug: a standard Base64 string breaks in a URL, and a Base64URL string may fail in tools expecting the standard alphabet. Know which variant your channel requires.

PropertyStandard Base64Base64URL
AlphabetA-Z a-z 0-9 + /A-Z a-z 0-9 - _
PaddingRequired (=)Often omitted
Safe in URLsNoYes
Used byEmail, most toolingJWT, web APIs, filenames

When Base64 is the right tool

  • Embedding small images or icons in HTML/CSS as data URIs
  • Transmitting binary attachments through text-only protocols (email, JSON fields)
  • Representing cryptographic material - keys, signatures, hashes - in config and headers
  • JWT header and payload segments (Base64URL)
  • Storing binary in text-based formats like JSON or CSV
  • Debugging - decoding a payload from a log line to inspect it

When NOT to use Base64

Base64 costs 33% size and adds CPU work. For large binary payloads, prefer binary channels: multipart uploads, typed arrays, or raw HTTP bodies.

For images, a data URI is only efficient for very small assets. Beyond a few kilobytes, the size overhead plus base64 inflation usually hurts more than the saved request helps.

And critically: Base64 is not a security measure. Encoded secrets are trivially readable - if you need confidentiality, encrypt first, then encode the ciphertext if the channel requires text.

Warning: Never treat Base64 as obfuscation for secrets, and never use it in place of an authenticated encryption scheme. 'Encoded' is not 'encrypted'.

Encoding in practice

// Binary -> Base64 in the browser
const bytes = new Uint8Array([77, 97, 110]); // 'Man'
let binary = '';
bytes.forEach(b => (binary += String.fromCharCode(b)));
const encoded = btoa(binary); // 'TWFu'
// Base64 -> Uint8Array
const decoded = atob(encoded);
const result = Uint8Array.from(decoded, c => c.charCodeAt(0));
// Node.js
Buffer.from('Man').toString('base64'); // 'TWFu'
Buffer.from('TWFu', 'base64').toString(); // 'Man'

FAQ

Q.Why is Base64 bigger than the original?

A.Because 3 input bytes (24 bits) become 4 output characters (also 24 bits of payload), the output is 4/3 the input - about 33% larger, before padding and line breaks.

Q.What does the = padding mean?

A.The = characters pad the final group so output length is a multiple of 4. They carry no data. Base64URL often omits them because the length is not important in that context.

Q.Is Base64 encryption?

A.No. Base64 is reversible encoding with no key. Anyone who sees the encoded value can decode it. For secrecy, use authenticated encryption (AES-GCM, ChaCha20) and encode the ciphertext only if the channel demands text.

Q.Why does my Base64 string break in a URL?

A.The + and / characters are not URL-safe: + can become a space and / can alter the path. Use Base64URL (- and _) for anything that travels in URLs, query strings, or filenames.

Q.Are data URIs worth it for images?

A.For tiny assets - a few hundred bytes to a couple of kilobytes - data URIs save a request and can be faster. For larger images, the 33% Base64 overhead plus the lost browser caching usually makes a separate file the better choice.

Q.Why does JWT use Base64URL without padding?

A.JWT segments appear in URLs and headers where +, /, and = are awkward. Base64URL's URL-safe alphabet plus unpadded form keeps tokens compact and unambiguous.

References

  • RFC 4648 – The Base16, Base32, and Base64 Data Encodings: https://www.rfc-editor.org/rfc/rfc4648
  • RFC 7515 – JSON Web Signature (JWS), Base64URL usage: https://www.rfc-editor.org/rfc/rfc7515
  • MDN – btoa() and atob(): https://developer.mozilla.org/en-US/docs/Glossary/Base64
  • MDN – data URIs: https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data

Encode or decode now

Base64, Base64URL, Hex, URL, and HTML, entirely client-side.

An encoding, not a security control

Base64 is the standard way to move binary through text channels - just remember the 33% size cost, the URL-safe variant, and that it provides zero confidentiality.

Encode and decode locally with the Encoder/Decoder - Base64, Base64URL, Hex, URL, and HTML, all in your browser.