Base64 Encode / Decode
Encode and decode Base64 with full UTF-8 support.
Auth headers and keys stay on your deviceEncode or decode Base64 online
About this Base64 encoder and decoder
Base64 turns any data into plain ASCII text, which is why it shows up everywhere: JWTs, data URLs, email attachments, basic auth headers, and API payloads. This tool encodes and decodes both directions with proper UTF-8 handling, so accented characters and emoji survive the round trip.
It also supports URL-safe Base64 (the variant using - and _ instead of + and /), which is what JWTs and many APIs use. Decoding a JWT segment? Paste it directly.
The mechanics are simple enough to hold in your head. RFC 4648 takes the input three bytes at a time — 24 bits — and rewrites each group as four characters carrying six bits each, drawn from a 64-symbol alphabet of A–Z, a–z, 0–9 and two extras. Four characters for every three bytes means the output length is 4 × ceil(n/3), roughly a third larger than the input: one mebibyte of data becomes 1,398,104 characters of Base64. When the input is not a multiple of three, the last group is padded with = so the length stays divisible by four. One leftover byte gets two padding characters, two leftover bytes get one, and an exact multiple of three gets none — which is why "A" encodes to QQ== and "AB" to QUI=.
The two alphabets differ in exactly two characters. Standard Base64 (RFC 4648 §4) uses + and / for values 62 and 63; the URL- and filename-safe alphabet (§5) uses - and _ instead, so the result survives a query string or a file name without escaping. Padding is required unless the spec referencing Base64 says otherwise, and JSON Web Signature does say otherwise: RFC 7515 defines base64url encoding as the §5 alphabet with all trailing = removed and no line breaks, which is why a JWT is three unpadded segments joined by dots. Email is the opposite case — RFC 2045 wraps Base64 message bodies at 76 characters per line. HTTP Basic authentication (RFC 7617) is plain Base64 of user-id, a colon, and the password, which is also why a user-id containing a colon is invalid, and why RFC 7617 says the scheme is not secure unless it runs over TLS. Data URLs follow the shape data:image/png;base64,… and default to text/plain;charset=US-ASCII when the media type is left out.
Where this page has limits, plainly. It is text in, text out: the decoder runs the resulting bytes through a UTF-8 decoder, so decoding a PNG or a ZIP gives you replacement characters, not a file. The encoder emits one unbroken line with no 76-character wrapping, so it is not a drop-in for a raw MIME body. Base64 that arrives already split across several lines — a PEM certificate body, an email source view — can come back as "Invalid Base64"; join it into one line first. And Base64 is an encoding, never encryption: it hides nothing, and it makes data about 33% bigger, so if your goal is smaller payloads, compress before you encode, not after.
The Base64 alphabet, padding, and the 33% size cost
Three bytes in, four characters out. Each output character carries exactly six bits, and 64 symbols are enough to represent all six-bit values. Everything else about Base64 follows from that ratio.
| Input | Bytes | Base64 |
|---|---|---|
| A | 1 | QQ== (two pad characters) |
| AB | 2 | QUI= (one pad character) |
| ABC | 3 | QUJD (no padding) |
| ABCD | 4 | QUJDRA== (back to two) |
| Ñ | 2 in UTF-8 | w5E= |
| café | 5 in UTF-8 | Y2Fmw6k= |
Note the last two rows: Ñ and café are one and four characters of text, but two and five bytes of UTF-8, and Base64 encodes bytes, not characters. This is where the browser’s legacy btoa() function goes wrong. btoa treats each character as one byte, so btoa("Ñ") returns 8Q== — the single Latin-1 byte F1, silently different from the correct UTF-8 answer w5E= — while any character above U+00FF, such as an emoji, makes it throw InvalidCharacterError outright. This tool runs the text through TextEncoder first, so the bytes are real UTF-8 before encoding begins.
Size is predictable: 4 × ceil(n/3) characters for n bytes, so 100 bytes become 136 characters (136%), 1 KiB becomes 1,368 (133.6%), and the ratio settles at 133.33% as the input grows. That overhead is why inlining a large image as a data URL costs you more bytes than linking it, and why MIME email attachments are meaningfully larger than the files they carry.
| Variant | Characters 62 and 63 | Padding |
|---|---|---|
| Standard (RFC 4648 §4) | + and / | Required unless another spec says otherwise |
| URL/filename-safe (§5) | - and _ | Often omitted; safe in query strings and file names |
| JWT segments (RFC 7515) | - and _ | Always stripped, and no line breaks at all |
| MIME email body (RFC 2045) | + and / | Required, wrapped at 76 characters per line |
Decoding is more forgiving than encoding: this tool converts - and _ back to + and / before decoding, and re-adds missing padding, so an unpadded JWT segment pastes in directly. What it will not do is turn Base64 back into a binary file — the output is always text — and it will not join Base64 that is already broken across lines, so strip the line breaks from a PEM body before pasting it.
FAQ
Why do accents break in other Base64 tools?
Many tools use the browser’s legacy btoa/atob functions, which only handle Latin-1. This tool encodes through UTF-8 bytes first, so any character works.
What is URL-safe Base64?
A variant that replaces + with - and / with _ so the result can be used in URLs and filenames without escaping. Enable the toggle to use it.
Is Base64 encryption?
No. It’s an encoding, not encryption — anyone can decode it. Never use it to protect secrets.