Base64 Encoder & Decoder

Encode and decode Base64 and URL-encoded text, UTF-8 safe.

Input
Output

What Base64 is actually for

Base64 is not encryption, and it is not compression. It is an encoding: a way to represent arbitrary binary bytes using 64 printable ASCII characters so they survive transport through systems designed for text. Its one property that matters is that the output is safe to put anywhere text is safe — an email body, a JSON string, a URL, an HTML attribute, a CSV field.

The cost is size: every 3 bytes of input become 4 characters of output, a fixed 33% overhead. That is why you should never Base64-encode something merely to "make it smaller" — it does the opposite.

How the encoding works

Take the input in groups of three bytes — 24 bits. Split those 24 bits into four 6-bit groups. Each 6-bit value (0–63) is looked up in the alphabet A–Z, a–z, 0–9, +, /. If the final group is not a multiple of three bytes, pad with = so the output length is always a multiple of four.

"Dev"  ->  D  e  v        (3 bytes = 24 bits)
       ->  01000100 01100101 01110110
       ->  010001 000110 010101 110110
       ->  17     6      21     54
       ->  R      G      V      2
"Dev" encodes to "RGV2"

The UTF-8 trap most encoders get wrong

This is the single most common source of "why does my decoded text look like garbage". JavaScript's built-in btoa() operates on Latin-1, not UTF-8. Any character above code point 255 — emoji, CJK, most accented text — throws an error or silently produces bytes that decode to something else.

btoa("café")        // throws: character out of range
btoa("你好")         // throws
btoa("🚀")          // throws

// Correct: encode UTF-8 bytes first
new TextEncoder().encode("🚀")   // Uint8Array [240, 159, 154, 128]
// -> base64: 8J+agA==

This tool encodes through TextEncoder and decodes through TextDecoder, so emoji and non-Latin scripts round-trip correctly. If you have ever used an encoder that mangled emoji, that was the bug.

Base64 vs. Base64URL

The standard alphabet includes + and /, both of which have special meaning in URLs — and = padding is awkward in query strings. Base64URL swaps + → - and / → _, and usually drops padding. This is the variant used by JWTs, and by many URL-safe token schemes.

Standard:  aGVsbG8/d29ybGQ/+
URL-safe:  aGVsbG8_d29ybGQ_

Mixing the two is a classic integration bug: a JWT with + in its signature arriving through a URL that decoded + as a space will fail signature verification, and the error message will not tell you why.

Where you will actually meet Base64

  • Data URLs — data:image/png;base64,iVBORw0… embeds a file inline in HTML or CSS. Convenient for tiny icons; wasteful for photographs, because it blocks caching and inflates the document by 33%.
  • HTTP Basic auth — Authorization: Basic dXNlcjpwYXNz is Base64 of user:pass. It is trivially reversible; it is obfuscation, not protection, and only meaningful over HTTPS.
  • JWTs — the three dot-separated segments are Base64URL-encoded JSON plus a signature.
  • Email (MIME) — attachments are Base64 because SMTP was designed for 7-bit ASCII text.
  • Embedding binary in JSON — JSON cannot hold raw bytes, so binary payloads travel as Base64 strings.

Base64 is not security

It is worth stating plainly because it comes up constantly: Base64 provides zero confidentiality. Anyone can decode it in one line. Never use it to hide a secret — not an API key, not a password, not a token. If you need confidentiality you need encryption (AES-GCM), and if you need integrity you need a signature (HMAC or a digital signature). Base64 gives you neither; it only gives you a text-safe representation of bytes.

Doing it from the command line

# Encode a file
base64 -i input.bin -o output.txt

# Decode
base64 -d encoded.txt > output.bin

# Encode a string without a trailing newline
printf '%s' 'hello world' | base64

Frequently asked questions

No. It is a reversible encoding with no key. Anyone can decode it instantly. Use it for transport safety, never for secrecy. If you need confidentiality, use AES-GCM; if you need integrity, use HMAC.

Base64 expands data by a fixed 33%: three input bytes become four output characters, plus padding. That overhead is the price of using only printable ASCII.

JavaScript's btoa() only accepts Latin-1 characters. Correct handling requires encoding the string to UTF-8 bytes first, which this tool does via TextEncoder.

A URL-safe variant that uses - and _ instead of + and /, and typically omits = padding. It is required for JWTs and anything embedded in a URL path or query string.

Yes, as a data URL — data:image/png;base64,…. It works well for icons under a few kilobytes. For larger images it blocks browser caching and inflates your stylesheet, so a normal file reference is better.