Skip to content
Kalio
Developer

Base64 encoder and decoder

Encode and decode Base64 with full Unicode support, including a URL-safe alphabet, and encode any file to Base64 without uploading it.


Encode a file instead

Drag a file here, or

The file is read in your browser. It is not uploaded.

Ready · runs on your device

Nothing is uploaded. This tool runs entirely inside your browser tab. Your files and figures stay on your device - we never receive them, so we cannot read, store or lose them.

How Base64 works

Base64 takes binary data and represents it using 64 characters that survive any text channel: A–Z, a–z, 0–9, + and /, with = for padding.

The mechanism is a regrouping of bits. Three bytes - 24 bits - are split into four 6-bit groups, and each group indexes into the 64-character alphabet.

Input:   M         a         n
ASCII:   77        97        110
Binary:  01001101  01100001  01101110
Regroup: 010011  010110  000101  101110
Index:   19      22      5       46
Output:  T       W       F       u

So Man encodes to TWFu. When the input length is not a multiple of three, = pads the output - one = if two bytes remain, two if one byte remains.

Where it is genuinely used

  • Email attachments. MIME has encoded binary this way since 1992, because SMTP was designed for 7-bit text.
  • Data URIs. data:image/png;base64,... embeds an image directly in HTML or CSS.
  • JSON Web Tokens. All three segments are URL-safe Base64.
  • HTTP Basic authentication. The Authorization header carries a Base64 of user:password - encoded, emphatically not encrypted, which is precisely why Basic auth requires HTTPS.
  • Binary in JSON. JSON has no binary type, so bytes travel as Base64 strings.
  • Cryptographic material. PEM certificates and SSH keys are Base64 with header lines.

The Unicode trap

The browser’s built-in btoa accepts only Latin-1. Passing it "héllo" throws, and passing it text that happens to survive can still corrupt on the way back.

The correct sequence is to encode the string to UTF-8 bytes first, then Base64 those bytes:

// Correct
const b64 = btoa(String.fromCharCode(...new TextEncoder().encode(text)));

// Broken for anything outside Latin-1
const b64 = btoa(text);

This tool does the former, which is why 日本語, Привет and 🎉 all survive a round trip intact.

Size, and when to inline

Base64 output is roughly 4/3 the size of the input. For a data URI in CSS, that overhead is offset by saving an HTTP request - worthwhile for a small icon under about 2 KB, and counterproductive above it. Large inlined assets bloat the stylesheet, cannot be cached separately, and block rendering while the CSS parses.

Base64 is not a security boundary

It is worth stating plainly because the mistake is so common. Base64 in a cookie, a URL parameter or a config file provides zero protection. If the data needs protecting, encrypt it and manage the key properly. If it merely needs to travel through a text channel, Base64 is exactly the right tool - and nothing more.

Common questions

Is Base64 encryption?

No, and treating it as such is a genuine security mistake. Base64 is a reversible encoding with no key - anyone can decode it instantly. It exists to move binary data safely through text-only channels, not to hide anything. Never use it to obscure credentials.

Why does encoding make my data bigger?

Base64 represents every 3 bytes as 4 characters, so output is about 133% of the input, plus padding. This is unavoidable - it is the cost of restricting yourself to 64 safe characters. It is why inlining large images as data URIs is usually a false economy.

What is URL-safe Base64?

Standard Base64 uses + and /, which have special meanings in URLs and must be percent-encoded. The URL-safe variant (RFC 4648 §5) substitutes - and _ and usually drops the = padding. JSON Web Tokens use it, which is why a JWT contains no + or / characters.

Why do some decoders mangle non-English text?

Because they use the browser's atob directly, which only handles Latin-1. Anything outside that range - accented characters, Cyrillic, Arabic, CJK, emoji - comes out corrupted. This tool converts through TextEncoder and TextDecoder, so UTF-8 round-trips correctly in every language.

Last reviewed