Base64 Encoder & Decoder
Result
Nothing to encode yet.
Text is converted to UTF-8 bytes before encoding, which is what every other base64 implementation does and what the browser’s own btoa does not: btoa is defined over Latin-1 and throws on any character above U+00FF, so “café” or an emoji breaks it. Encoding always grows the data by a third, because three bytes become four characters.
Bytes that survive a text-only channel
Base64 exists so that arbitrary bytes can travel through something built for text: an email header, a JSON string, a data: URI, a certificate in a config file. This encoder and decoder runs both directions on either alphabet, with padding on or off and optional wrapping at 76 characters. A send-back button feeds the output into the input, so a round trip can be checked in one click, and the change in size is reported.
Worked examples, and the padding rule
“Hello, World!” encodes to SGVsbG8sIFdvcmxkIQ==. The trailing equals signs are padding, and the rule is clearest on the specification’s own test vectors: “f” becomes Zg==, “fo” becomes Zm8=, “foo” becomes Zm9v and “foobar” becomes Zm9vYmFy.
Encoding works in groups of three bytes, and each group becomes four characters. A final group of one byte is padded with two equals signs and a group of two with one, while a group that comes out even needs none. So 10 bytes encode to 16 characters padded, or 14 unpadded — padding carries no data, it only keeps the length a multiple of four.
Two alphabets, and when the second one matters
The format is defined by RFC 4648. Section 4 gives the standard alphabet — A to Z, a to z, 0 to 9, plus and slash — padded with equals signs. Section 5 gives the URL and filename safe alphabet, which swaps plus for hyphen and slash for underscore, and is conventionally used without padding.
The substitutions are not arbitrary: plus, slash and equals are precisely the characters that break in a URL, a query string or a filename. Decoding here accepts either alphabet, padded or not, and ignores whitespace in the input, because a value copied out of an email header arrives wrapped across several lines.
Accented letters, emoji, and the browser’s own btoa
Browsers ship a built-in btoa(), and it is defined over Latin-1: it throws on any character above U+00FF, so one accented letter or emoji is enough to break a naive implementation. This tool converts the text to UTF-8 bytes first and encodes those, which is what every other base64 implementation does, so “café ☕” encodes to Y2Fmw6kg4piV and comes back unchanged.
In the other direction, not everything that decodes is text. Feed in an encoded image and the result is reported as bytes that are not valid UTF-8, rather than as a screen of replacement characters that would look like a fault.
An encoding, not encryption
Base64 conceals nothing. It is reversible by anyone who recognises the format, and offers no confidentiality whatsoever — a token sitting in base64 in a log file is sitting there in the clear. Anything that has to stay secret must be encrypted; this only makes bytes safe to carry.
The cost of carriage is size. Three bytes becoming four characters means the data grows by about a third, which is why an attachment inflates the message carrying it, and why an over-long data: URI or cookie can be rejected for exceeding a limit the raw bytes fitted inside.
The equals signs, the two alphabets and the size increase
Can I use base64 to hide a password?
No. It reverses in seconds, and the decoder above will do it for anyone who pastes the string in. Base64 is a transport format; secrecy needs real encryption.
Do I need the equals signs on the end?
It depends on what is reading it. Padding keeps the length a multiple of four and strict decoders expect it, while URL-safe values in tokens are usually unpadded.
Why is the encoded version longer than what I put in?
Because four characters are emitted for every three bytes, so the output runs roughly a third longer before any wrapping is counted. Encoding never compresses: compress first, encode afterwards.
The decoder says the result is not valid UTF-8. What does that mean?
The base64 itself decoded correctly, but the bytes underneath are not text — usually an image, a PDF or an archive. They are real bytes, they simply are not characters.
Why does an attachment make an email so much bigger?
Because a mail body is text, so every attached byte travels as base64 and grows by about a third, with a line break every 76 characters added on top.
When is a data: URI worth using?
It inlines a whole file into a URL, the bytes written as base64 after the media type, which saves a request and suits a small icon in a stylesheet. It costs a third more bytes and cannot be cached separately, which rules it out for anything large.