GlobalKit

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

TextBase64Note
fZg==RFC 4648 test vector, 1 byte, two = signs
foZm8=2 bytes, one =
fooZm9v3 bytes, no padding
foobarZm9vYmFy6 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 paddingZg and Zm8Padding 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

Frequently asked questions

Last updated: 10/11/2026

Related tools