Base64 Encoder and Decoder
Encode text to Base64 or decode it back. Text is converted as UTF-8, so ş, ğ and emoji work. Choose the URL-safe alphabet, padding and line breaks.
Up to 500,000 characters. Nothing leaves your device.
Uses - and _ instead of + and / (RFC 4648 section 5), so the result can sit in a URL or a file name.
Pads the result with = to a multiple of 4 characters.
Wraps the output with a line feed every 64 characters (PEM style) or every 76 characters (MIME style).
0 bytes encoded to 0 characters.
Base64 is an encoding, not encryption. Anyone can decode it, so never use it to protect secrets.
How it works
Base64 turns bytes into text. Three bytes (24 bits) are split into four groups of 6 bits, and each group is written as one character from a 64-character alphabet: A–Z, a–z, 0–9, + and / (RFC 4648 section 4). Because 3 bytes always become 4 characters, the output is about a third larger than the input.
If the input does not end on a multiple of 3 bytes, the last group is shorter. One leftover byte produces 2 characters and ==, two leftover bytes produce 3 characters and = (section 3.2). The = signs are padding that brings the length to a multiple of 4. They carry no data, so you can drop them and the decoder here will still accept the result.
Text comes first as bytes. The tool encodes your text as UTF-8 and then encodes those bytes. That is different from btoa(text), which throws on any character above U+00FF and, for characters between U+0080 and U+00FF, encodes Latin-1 rather than UTF-8, so other tools would decode it differently. A lone surrogate cannot be written in UTF-8; it is replaced by U+FFFD and will not round-trip.
URL-safe alphabet. Section 5 of the RFC swaps + and / for - and _. The same 6-bit values, a different spelling.
Line breaks. 64 characters per line is the PEM style (RFC 7468), 76 is MIME (RFC 2045 section 6.8). The tool uses LF only and never ends the output with a break.
Decoding is forgiving on purpose
Pasted data is messy, so the decoder ignores spaces, tabs and line breaks anywhere, accepts both alphabets, and accepts missing padding. Padding that is present must be correct: = only at the end, at most two, and the total a multiple of 4. Any other character is an error, and so is a data length of 1 mod 4. Unused trailing bits that are not zero are accepted and ignored.
The decoded bytes are then read as UTF-8. If they are not valid UTF-8, you choose: replace the bad bytes with U+FFFD and show a warning, or show an error. A leading byte order mark is kept as U+FEFF, not removed.
Examples
| Text | Base64 | Note |
|---|---|---|
| f | Zg== | RFC 4648 test vector, 1 byte, two = signs |
| fo | Zm8= | 2 bytes, one = |
| foo | Zm9v | 3 bytes, no padding |
| foobar | Zm9vYmFy | 6 bytes become 8 characters |
| ş | xZ8= | UTF-8 bytes C5 9F; btoa("ş") throws |
| ğ | xJ8= | UTF-8 bytes C4 9F |
| ü | w7w= | UTF-8 bytes C3 BC, two bytes, not the single Latin-1 byte |
| ??> | Pz8+ | Standard alphabet |
| ??> | Pz8- | URL-safe alphabet |
| ??? | Pz8/ and Pz8_ | Standard and URL-safe |
| f, fo without padding | Zg and Zm8 | Padding switched off |
Sizes. The text şğ followed by the emoji 🎉 is 2 + 2 + 4 = 8 UTF-8 bytes, so it encodes to ceil(8 / 3) × 4 = 12 characters. 100 times the letter a is 100 bytes and 136 characters with padding; wrapped at 76 it gives lines of 76 and 60 characters, wrapped at 64 it gives 64, 64 and 8. The 5 bytes of fooba take 7 characters without padding.
Errors and lossy decoding. Zg=, Zg===, Zm9v! and Z are all rejected. The input //5B is the bytes FF FE 41, which are not valid UTF-8: with replacement you get two U+FFFD characters followed by A, the warning appears, and the byte count says 3. With the error option you get an error instead.
Things to watch for
- Do not treat Base64 as protection. An API key written in Base64 is still an API key. Encryption needs a key; Base64 does not have one.
- Both sides must agree on UTF-8. Output from this tool decodes correctly anywhere that assumes UTF-8. Data made by
btoa()on text with accented letters may be Latin-1 and decode differently here. =and+need care inside URLs. In a query string=is a delimiter and+can be read as a space. Choose the URL-safe alphabet, or percent-encode the value with the URL encoder.- Text only. Decoding binary content such as an image or an archive gives meaningless characters. Use the error option to see right away that the bytes are not text.
- Replacement is lossy. Once bytes are replaced by U+FFFD, you cannot get the original bytes back from the text on screen.
- Limits. Text input is limited to 500,000 characters, and the decoder accepts up to 2,100,000 characters of Base64, which is enough for anything the encoder can produce.
- Privacy. Conversion happens in your browser. What you type or paste is not uploaded.
Frequently asked questions
Last updated: 10/11/2026
Related tools
Percent-encode or decode text for URLs as a component, a whole URL or form data, and see the parts of any http or https address. Nothing is fetched.
Validate JSON against RFC 8259, pretty-print it with 2 or 4 spaces or tabs, or minify it. Errors come with line and column. Nothing is uploaded.
Generate random (v4) or time-ordered (v7) UUIDs, up to 100 at once, and check what an existing UUID contains. Everything runs in your browser.