QuickUse Generator

Base64 Encoder/Decoder

Encode or decode Base64 in your browser. UTF-8 safe, padding toggle, URL-safe auto-detect on decode. 100% client-side.

Mode
Padding
0 / 10000 chars
Base64 output
The Base64 output appears here as you type.

Editorial guide

About this generator

An honest technical read on what is happening behind the Generate button.

Base64 is the duct tape of the internet — the universal way to move binary data through text-only channels. Email attachments since the early 1990s, JWT tokens, data URIs in CSS, HTTP Basic Auth headers, certificates in PEM format. Whenever a system that handles bytes meets a protocol that expects printable characters, Base64 is the layer between them.

What Base64 actually does

Base64 takes a stream of arbitrary bytes and re-encodes it using a 64-character alphabet that survives transport through ASCII-only systems. Three input bytes (24 bits) become four output characters (4 × 6 bits = 24 bits). When the input length isn't a multiple of three, the encoder pads with one or two = characters so the output length is always a multiple of four. The cost is fixed: the encoded form is roughly 33% larger than the raw bytes.

This is not encryption, not compression, and not a hash. Base64 is fully reversible by anyone who reads it. Treat it as a transport encoding, never as a security mechanism. The number of "I Base64-encoded the password" security bugs in production is genuinely startling.

A brief history

The encoding predates the modern internet. RFC 989 (1987) and RFC 1421 (1993) defined Privacy-Enhanced Mail (PEM), which used a 64-character ASCII subset to embed RSA-signed messages and certificates in email bodies. RFC 1521 (1993, MIME) generalized the encoding for all email attachments — that's where the line-wrap-at-76-chars convention comes from. Today the canonical reference is RFC 4648 (2006), which unified the family: §4 covers standard Base64, §5 covers the URL-safe variant (Base64URL), and §6–§9 cover Base32 and Base16/hex.

Padding: keep it or strip it

The = trailing characters serve one purpose: they let the decoder know how many bytes the original input had when the count wasn't divisible by three. Modern APIs increasingly strip the padding because the length is already implicit and the = is awkward in URLs (it has its own meaning in query strings) and JSON (no semantic baggage, but it's noise).

The toggle in this tool exists because both conventions are alive in production. RFC 7519 (JSON Web Tokens) and RFC 8037 (OKP JWKs) require unpadded Base64URL. RFC 4648 §4 standard Base64 keeps the padding by default. When you encode something to drop into a URL parameter, use unpadded. When you encode something to drop into an HTTP Authorization: Basic header (RFC 7617), keep the padding.

Standard vs URL-safe — same bytes, different alphabet

Standard Base64 uses A-Z a-z 0-9 + /. The + and / characters are not safe in URLs: + is interpreted as a space when a server percent-decodes a query string, and / is the path separator. So RFC 4648 §5 defines the URL-safe variant: - replaces + and _ replaces /. The underlying bytes are identical — only the encoding alphabet changes.

The decoder in this tool auto-detects which alphabet you pasted. If it sees a - or _, it treats the input as URL-safe and translates back to +// before calling atob. If it sees a + or /, it treats the input as standard. If it sees neither (the input is just letters and digits), it defaults to standard — both alphabets agree on [A-Za-z0-9].

Where you'll actually meet Base64

  • HTTP Basic Auth (RFC 7617): the Authorization header is Basic ${base64(username:password)}. The Base64 here is for transport, not secrecy — anyone who sees the header can decode it. Use HTTPS.
  • JSON Web Tokens (RFC 7519): three Base64URL-encoded segments separated by dots. The first two segments are JSON (header + payload) that you can decode without a key. Only the signature requires the secret.
  • Data URIs (RFC 2397): data:image/png;base64,iVBORw0KGgoAAA… embeds a file directly in HTML or CSS. Useful for small icons, terrible for large images — the 33% size overhead defeats HTTP compression.
  • PEM certificates (RFC 7468): the -----BEGIN CERTIFICATE----- blocks you see in TLS configs are Base64-wrapped DER bytes with line breaks every 64 chars.
  • Email attachments (MIME, RFC 2045 §6.8): every attachment in an email since the 1990s travels as Base64-encoded bytes, line-wrapped at 76 characters.

Quick debugging recipes

Most production "Base64 problem" tickets resolve to one of a handful of failure modes. When a decoder rejects the input, check whether the source produced URL-safe characters and the destination expected standard alphabet (or vice versa). When a JWT debugger tells you the signature is invalid but the payload looks correct, the encoded header almost always lost or gained a = in a careless copy-paste. When a binary file decodes to garbage, you probably ran the bytes through a UTF-8 decoder somewhere along the path — Base64 is not UTF-8 and not all decoded bytes are text. Thefatal: true flag on TextDecoder, which this tool uses, catches that case explicitly rather than masking it with replacement characters.

The 33% tax, and what alternatives buy you

Every encoding that turns binary into text pays a size tax. Base64 maps 3 bytes (24 bits) into 4 characters (24 bits of information across 4 × 8-bit code units = 32 bits on the wire), so the floor is exactly 33.33% overhead. Add padding and the worst case becomes 33.33% + up to 2 chars. Add MIME line-wrapping at 76 characters and you also pay 2 chars per 76 for the CRLF. So a 1 MB binary file lands at roughly 1.37 MB Base64-encoded with MIME wrap, or about 1.33 MB without wrap.

Why is Base64 the dominant choice when alternatives exist? Base32 (RFC 4648 §6) is more human-friendly — no case sensitivity, no easily-confused glyphs — but inflates to 60% overhead. Base85/ASCII85 (used in PDF and Git diffs) drops to 25% overhead but uses characters like !, ", and < that don't survive most transport layers. Base122 squeezes further but assumes UTF-8 transport end-to-end. Base64 sits at a Goldilocks point: 33% overhead, an alphabet that fits in 7-bit ASCII, and four decades of universal tooling support. The economics rarely favor anything else.

Compression is the better lever when size matters. Gzipping a 1 MB binary down to 300 KB and then Base64-encoding gets you to 400 KB on the wire — better than the 1.33 MB you'd get from Base64-only. The order matters: compress, then encode. Encoding before compressing means the gzip compressor sees a high-entropy 64-character alphabet and finds almost nothing to squeeze.

UTF-8 and the btoa trap

The browser's built-in btoa() function only accepts characters in the 0–255 byte range. Calling btoa('日本語') throws InvalidCharacterError. The correct path is TextEncoder → bytes → binary string → btoa, which is what this tool does internally. If you ever see "InvalidCharacterError" while encoding Base64 in JavaScript, you're calling btoa directly on a multi-byte string. The fix is one line: encode to UTF-8 first.

Privacy: nothing leaves your browser

Server-side Base64 tools log the input you typed via load balancer logs, request mirrors, application logs, and any analytics middleware that captures POST bodies. That matters when the input is a password (Basic Auth headers), a JWT payload, a draft certificate, or a data URI of a sensitive screenshot. This tool runs the entire encode/decode pipeline locally — the Web platform's btoa and atob functions are part of every modern browser and need no network call. The recent-inputs dropdown is also privacy-preserving: it remembers your input and the chosen mode (encode-padded, encode-unpadded, decode), and recomputes the output on recall. The output itself is never written to disk.

Frequently asked questions

Is Base64 a form of encryption?

No. Base64 is an encoding — fully reversible by anyone who reads the output. It exists to transport binary data across text-only channels (email, URLs, HTTP headers, JSON). If you need actual confidentiality, use TLS for transport and a real cipher (AES, ChaCha20) for at-rest data. "I Base64-encoded the password" is a common production bug, not a security control.

Why does my output sometimes have one or two = at the end?

Padding. Base64 emits four characters for every three input bytes. When the input isn't a multiple of three, the encoder pads with one or two `=` so the output length is always a multiple of four. Unpadded Base64 (RFC 4648 §5 and the JWT spec) strips them because the length is already implicit. This tool lets you toggle the behavior in Encode mode; the decoder accepts both.

What is the difference between Base64 and Base64URL?

Same encoding, different alphabet. Standard Base64 uses `+` and `/` for the 62nd and 63rd characters. Base64URL (RFC 4648 §5) replaces them with `-` and `_` so the result is safe inside URLs and filenames. The byte payload is identical. The decoder in this tool auto-detects which alphabet you pasted and translates internally.

Can I decode this in the shell?

Yes. On macOS and Linux: `echo -n "SGVsbG8=" | base64 -d`. On Windows PowerShell: `[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("SGVsbG8="))`. Both expect standard alphabet with padding — for Base64URL you may need to substitute `-`/`_` back to `+`/`/` and add `=` first, or use a flag like `base64 -d --decode` with platform-specific extras.

Why does my JavaScript btoa() throw on non-ASCII input?

`btoa` is a 1995-era API that only accepts characters in the 0–255 byte range. Calling `btoa('日本語')` throws InvalidCharacterError. The correct path is `btoa(String.fromCharCode(...new TextEncoder().encode(input)))`, which is what this tool does internally. The TextEncoder produces UTF-8 bytes, and `btoa` is then fed a binary string of those bytes.

Does Base64 increase the size of my data?

Yes — by exactly 33% for the encoded payload (3 bytes in, 4 chars out), plus up to 2 chars of padding, plus 2 chars per 76 input chars when MIME line-wrap is applied. For a 1 MB file that means roughly 1.33 MB encoded, or 1.37 MB with MIME wrap. If size matters, compress (gzip) before encoding, not after — compressed Base64 is almost incompressible.

Is Base64 case-sensitive?

Yes. The alphabet treats `A` and `a` as distinct characters. `SGVsbG8=` decodes to "Hello"; `sgvsbg8=` decodes to gibberish. If you need case-insensitive transport, Base32 (RFC 4648 §6) is the canonical alternative — at the cost of 60% size overhead instead of 33%.

My decoder rejected the input. What went wrong?

Three usual culprits. (1) The input was copied from a context that mangled the alphabet — replacing `+` with a space, or stripping `=`, or splitting the string with stray whitespace. This tool tolerates whitespace and auto-pads, but truly missing characters can't be recovered. (2) The bytes were not text. A decoded Base64 of a PNG or binary blob will look like garbage when forced through a UTF-8 decoder; that's not a bug, the source data was binary. (3) The length is mathematically impossible — Base64 length mod 4 should be 0, 2, or 3, never 1.