Base64 Encoder & Decoder
What Base64 Actually Does
Base64 encodes arbitrary binary data as text using 64 printable characters. It exists because a great many systems — email headers, JSON documents, URLs, HTTP headers, XML attributes — are specified to carry text, and handing them raw bytes leads to corruption the moment a byte happens to look like a control character or a delimiter.
The mechanism is simple arithmetic. Three bytes are 24 bits; 24 bits split evenly into four 6-bit groups; each 6-bit group indexes one of 64 characters. That three-to-four ratio is why Base64 output is always about 33% larger than its input, and why the encoded length is always a multiple of four once padding is applied. When the input length is not divisible by three, the final group is padded with = characters to complete the block.
Base64 vs Base64URL
Standard Base64 uses + and / as its final two characters. Both are problematic in URLs: / is a path separator and + is interpreted as a space in query strings. Base64URL, defined in RFC 4648 §5, substitutes - and _ instead, and usually drops the = padding because = also carries meaning in query strings.
| Aspect | Base64 | Base64URL |
|---|---|---|
| Character 62 | + | - |
| Character 63 | / | _ |
| Padding | =, usually required | Usually omitted |
| Safe in a URL | No | Yes |
| Typical use | Email, data URIs, HTTP Basic auth | JWTs, JWKs, URL parameters |
This tool detects which alphabet your input uses when decoding, and tells you rather than silently normalising it. A string containing characters from both alphabets is rejected outright, because that is not valid in either variant and almost always means two encoded values were concatenated by mistake.
The UTF-8 Trap
This is the defect that separates a correct Base64 tool from a broken one. In JavaScript, the built-in btoa() function operates on "binary strings" — strings in which every character represents exactly one byte. Any character above U+00FF throws an exception. Pass it an emoji, a Chinese character, or even an accented Latin letter, and it fails.
The correct approach is to convert the text to UTF-8 bytes first, then Base64-encode those bytes. That is what this tool does, which is why Grüße and rocket emoji encode and decode without corruption. Many online encoders skip this step and either throw an error or, worse, silently mangle the text.
// Broken — throws on any non-ASCII input
btoa("Grüße");
// Correct — encode to UTF-8 bytes first
const bytes = new TextEncoder().encode("Grüße");
btoa(String.fromCharCode(...bytes));
The byte counts shown above the output make this visible. A rocket emoji is a single character to a human but four bytes in UTF-8, and it is the byte count that determines the encoded length.
Where You Will Meet Base64
- JSON Web Tokens. Every segment of a JWT is base64url-encoded JSON. Paste a single segment here to read it, or use our JWT decoder to handle the whole token at once.
- JSON Web Keys. The RSA modulus and EC coordinates in a JWKS are base64url-encoded big-endian integers — see our JWKS decoder for the structure around them.
- HTTP Basic authentication. The
Authorizationheader carriesbase64(username:password), which is exactly why Basic auth over plain HTTP is indefensible: the credentials are one decode away. - Data URIs. Inlining a small image as
data:image/png;base64,…avoids an HTTP request at the cost of roughly 33% more bytes. - Email attachments. MIME uses Base64 because SMTP was specified for 7-bit ASCII and cannot carry arbitrary bytes safely.
- Kubernetes secrets. Values in a Secret manifest are Base64-encoded, which is an encoding step for transport, not a security control — a point that causes real confusion.
Reading Padding
The = characters at the end are not decoration; they signal how many bytes the final group actually holds. One = means the last group decodes to two bytes, and two = means it decodes to one. Because that information is recoverable from the string length alone, many systems omit padding entirely — which is why base64url values in JWTs rarely have any.
This decoder accepts input with or without padding and restores it internally. It does reject a string whose length leaves a remainder of one when divided by four, because no valid Base64 string can have that length; encountering it means characters were lost or added in transit.
Decoding Binary Data
Not everything encoded in Base64 is text. Images, compressed archives, and cryptographic keys are all commonly Base64-encoded, and decoding them produces bytes that are not valid UTF-8. Rather than displaying replacement characters and pretending it worked, this tool detects that case, tells you the content is binary, and shows a hex dump of the bytes instead. The reported byte count is accurate either way.