Base64 Encode and Decode

Convert text or files to Base64 or Base64URL and back, with full UTF-8 support.

Base64 output

Overview

Base64 represents arbitrary bytes using 64 printable ASCII characters, so binary data can travel through channels that only handle text: JSON fields, HTTP headers, email bodies, environment variables and HTML attributes. You run into it when you embed an image as a data: URI, read an Authorization: Basic header, inspect a Kubernetes secret, or look at the middle segment of a JWT.

This tool encodes text as UTF-8 before converting it, so accented letters, CJK and emoji survive the round trip. Decoding is forgiving about line breaks, missing = padding and the URL-safe alphabet, and it is strict about real mistakes, telling you which character is wrong and where. If the decoded bytes are not text, it identifies common file types and lets you download the file. Encoding and decoding happen in your browser; nothing you paste or open is uploaded.

How Base64 works: 3 bytes become 4 characters

The encoder takes the input three bytes (24 bits) at a time and splits those 24 bits into four 6-bit groups. Each group is a number from 0 to 63, which indexes into the alphabet A–Z, a–z, 0–9, +, /. Here is the classic example, the ASCII string Man:

StepValue
CharactersM · a · n
Bytes77 · 97 · 110
Bits01001101 01100001 01101110
6-bit groups010011010110000101101110
Index1922546
Base64TWFu

So Man encodes to TWFu. When the input length is not a multiple of three, the last group is padded with zero bits and the output is filled out with = so it is still a multiple of four characters: Ma becomes TWE= and M becomes TQ==. One = means the final group held two bytes, two mean it held one.

Because every 3 bytes turn into 4 characters, Base64 output is about 33% larger than the input (4/3 of the size, rounded up to a whole group). MIME email adds a line break every 76 characters on top of that, which is what the Wrap at 76 option produces.

Base64 vs Base64URL

Standard Base64 is defined in RFC 4648 section 4. Its + and / characters cause trouble in URLs and file names: + is read as a space in query strings and / is a path separator. Section 5 defines the "URL and filename safe" alphabet, which swaps them for - and _. Padding is often dropped as well, since the decoder can work out the length.

Base64Base64URL
Characters 62 and 63+ /- _
PaddingRequired =Usually omitted
Bytes FB FF+/8=-_8
Typical useMIME, PEM, data: URIs, Basic authJWTs, URL parameters, file names

Most "invalid Base64" errors in practice come from feeding one variant to a decoder that only accepts the other. This decoder accepts both and adds missing padding. If you need to put standard Base64 into a query string, either switch to Base64URL or percent-encode it with the URL encoder.

Where you will see Base64 (and why it is not encryption)

  • Data URIs: <img src="data:image/png;base64,iVBORw0KGgo..."> inlines a small image into HTML or CSS. Use the data: URI output with Encode file to produce one.
  • HTTP Basic auth: Authorization: Basic dXNlcjpwYXNz is just user:pass encoded, as described in RFC 7617.
  • Email attachments: MIME (RFC 2045) sends binary attachments as Base64 wrapped at 76 characters per line.
  • JWTs: each of the three dot-separated parts is Base64URL without padding. Paste a whole token into the JWT decoder to see the header and claims.

Base64 has no key and no secret. Anyone who sees dXNlcjpwYXNz can decode it in a second, which is why Basic auth is only acceptable over HTTPS and why a Base64 value in a Kubernetes secret is not protected by the encoding. If you need to check that data was not changed, use a hash from the hash generator; if you need to hide it, use real encryption.

The atob / btoa Unicode pitfall

The browser's built-in btoa() works on "binary strings", where each character must be in the range 0–255. Pass it anything outside Latin-1 and it throws:

btoa('✓ done');
// Chrome: InvalidCharacterError: Failed to execute 'btoa' on 'Window':
//   The string to be encoded contains characters outside of the Latin1 range.

The opposite mistake is quieter. atob() returns one character per byte, so decoding UTF-8 text with it turns é (bytes C3 A9, Base64 w6k=) into the mojibake é. The fix in both directions is to convert between strings and UTF-8 bytes explicitly:

function utf8ToBase64(str) {
  const bytes = new TextEncoder().encode(str);
  let binary = '';
  for (const b of bytes) binary += String.fromCharCode(b);
  return btoa(binary);
}

function base64ToUtf8(b64) {
  const binary = atob(b64);
  const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));
  return new TextDecoder().decode(bytes);
}

Newer browsers also ship Uint8Array.prototype.toBase64() and Uint8Array.fromBase64(), which handle the alphabet and padding for you; check MDN for support before relying on them. In Node.js, Buffer.from(str).toString('base64') and Buffer.from(b64, 'base64').toString('utf8') already use UTF-8.

Frequently Asked Questions

Is Base64 a form of encryption?

No. Base64 is a reversible encoding with a public alphabet and no key. It makes binary data safe to transport as text, but anyone can decode it, so never use it to hide passwords, tokens or personal data.

Why does my Base64 string end with = or ==?

The equals signs are padding. Base64 works in groups of three input bytes; if the last group has only two bytes you get one =, and if it has one byte you get two. Base64URL usually leaves the padding out, and this decoder accepts input with or without it.

Why does decoded text show characters like é or �?

The bytes are UTF-8 but were interpreted as Latin-1, typically by calling atob() directly. Decode the bytes with TextDecoder as shown above. A replacement character (�) means the bytes are not valid UTF-8 at all; this tool shows such data as hex instead of guessing.

How much bigger does Base64 make my data?

About 33%: every 3 bytes become 4 characters, plus up to two padding characters. Wrapping at 76 characters adds a line break per line, roughly another 1–3% depending on whether the line ending is LF or CRLF. The status bar shows the exact numbers for your input.

Can I decode a Base64 image or PDF back to a file?

Yes. Switch to Decode and paste the Base64 or the full data: URI. If the result is binary, the tool recognises PNG, JPEG, GIF, PDF, ZIP and gzip from their first bytes and offers a Download decoded file button with the right extension.

Are my text and files uploaded anywhere?

No. Encoding and decoding run in JavaScript in your browser, and files are read locally with the File API. Your last text input is kept in this browser's local storage so it survives a refresh; click Clear to remove it.