Guide

How to Encode and Decode Base64 (With Unicode Support)

Learn how to convert text to Base64 and back, including correct handling of emojis and non-Latin characters.

By Sorawi Tools Team · Published July 1, 2026

What Base64 Is and Why It Exists

Base64 is an encoding scheme that converts binary data into a safe ASCII representation. It exists because many channels that carry data understand only text: email bodies, JSON payloads, URL query strings, and certain database fields. Binary data, which can contain any byte value including zero bytes and control characters, gets mangled or rejected on such channels, so instead of sending raw bytes you represent them with a 64-character alphabet of letters, digits, and a couple of symbols. The alphabet is A through Z, a through z, 0 through 9, plus and slash, which covers 64 characters and gives the scheme its name. Whatever binary content you have, an image, a small document, an encryption key, a signature, a compressed blob, base64 renders it as printable text that survives any transport intact. The price of that universality is size. Every three input bytes become four output characters, a roughly 33 percent expansion, so a 3 MB file becomes about 4 MB of base64 text. That overhead is why you reach for base64 selectively: embedding a small image inline, transmitting binary in a text-only API, or storing a token, not for moving large files around when a binary channel exists. It is equally important to understand what base64 is not. It is not encryption and provides no confidentiality whatsoever; it is a reversible representation, and anyone who can read the encoded text can decode it instantly. Treat base64 like a shipping crate, a way to move bytes through a text-only world, not like a lock.

How Base64 Encoding Actually Works

The mechanics are simple once you see them. Base64 reads the input as a stream of bytes and groups them three at a time, for 24 bits per group. It then slices those 24 bits into four chunks of six bits each, and maps each six-bit value, which ranges from 0 to 63, to one character in the 64-character alphabet. Three bytes in, four characters out. The classic worked example is the three bytes for Man, hexadecimal 4D 61 6E, which encode to the four characters TWFu. This is why encoding is deterministic: the same input bytes always produce the same output text. Padding is the detail that trips people up. The input is not always a multiple of three bytes, and when it is not, the final group contains only one or two bytes, producing an incomplete 24-bit chunk. The standard handles this by encoding what is there and adding equals signs as filler: one byte remaining produces two characters plus two equals signs, and two bytes remaining produce three characters plus one equals sign. So the letter A encodes to QQ==, and the letters AB encode to QUJ=. Decoders use the equals signs to know how much real data remains. There are also two alphabet variants to know about. URL-safe base64 substitutes minus and underscore for plus and slash, because those two characters are special inside URLs, and it often omits padding entirely. Different tools produce slightly different output because of these choices, which is why base64 text from one system sometimes needs cleanup before another system accepts it.

How to Encode and Decode with the Base64 Tool

Encoding and decoding with the Base64 tool is instant and runs entirely in your browser, so your text never leaves your device. The tool handles both directions, plain and URL-safe output, and full Unicode input, which makes it a one-stop replacement for console tricks.

  1. 1Open the Base64 Encode & Decode tool in your browser
  2. 2Choose whether you want to encode or decode with the mode switch
  3. 3Paste your plain text, or your base64 string, into the input area
  4. 4Select standard or URL-safe alphabet if your use case needs the URL-safe variant
  5. 5Click Encode to Base64 or Decode from Base64
  6. 6Copy the result from the output area

Unicode: Why btoa and atob Fail, and What Works

The classic browser functions btoa and atob break the moment your text contains anything beyond basic Latin characters. btoa works on Latin-1, a narrow byte encoding, so it throws an error or produces mojibake for accented characters like é, let alone emoji like the smiley face, Vietnamese characters like ế, Chinese hanzi, or Arabic script. The common workaround of running encodeURIComponent and then replacing percent escapes is a hack that produces encoded output no other system recognizes as valid base64, and it silently mangles text at the boundaries. These failures are not bugs in your code; they are a mismatch between a byte-oriented scheme and the modern Unicode strings that applications actually handle. The correct approach is to convert the text to UTF-8 bytes first, then base64 the bytes. UTF-8 is the encoding that represents every Unicode character, so the emoji, the accented letter, and the multi-byte scripts all become a precise sequence of bytes, and base64 then encodes those bytes losslessly. Decoding runs the pipeline in reverse: base64 decodes to bytes, and the bytes are interpreted as UTF-8 text. The Base64 tool does exactly this. Encode Café with a non-Unicode-aware tool and you may get a throw or garbage; encode it with a UTF-8-aware tool and you get a string that decodes back to Café on any platform, which is the round-trip guarantee you actually need when handling international text, emoji, and user-generated input. The same principle extends beyond text. Any binary payload, whether it is a small PNG, a PDF, or a key file, is a stream of bytes, and encoding the bytes directly is lossless. Text inputs just require the extra step of choosing UTF-8 as the intermediate representation, because text has to become bytes before it can be encoded at all. When you paste arbitrary bytes or text into a UTF-8-aware encoder, the result is deterministic and reversible, which is the property that makes base64 useful for real round-trips rather than toy examples.

Common Base64 Mistakes

The most common mistake is treating base64 as a security mechanism. It is not; encoding is a reversible transformation, so base64-encoding a password or a license key protects nothing, and anyone who can see the encoded value can recover the original in seconds. The second is assuming every base64 string is interchangeable. Output varies by padding, alphabet, and line wrapping: some email tooling wraps MIME base64 at 76 characters, some decoders choke on the whitespace that wrapping introduces, and URL-safe variants use different characters and may omit padding. If a string with an equals sign in the middle fails to decode, look at the whitespace and the alphabet before suspecting corruption. The third is silent decoding. Decoding a corrupted or truncated base64 string can succeed and produce garbage bytes, so validate that the input actually is well-formed base64 before trusting the output. Other failures are easy to make and easy to catch. Adding or dropping padding produces an off-by-one error that breaks the final bytes. Pasting a string that contains newlines, because it was wrapped in an email or a file, breaks decoders that do not tolerate whitespace. Using base64 for small data when hex would be clearer, or when URL-encoding would be shorter, overcomplicates the solution. And the asymmetry trap: an encoded string must be decoded with the same alphabet and padding convention that produced it, so mixing standard and URL-safe variants, or padded and unpadded forms, produces wrong output. When a decode looks almost right but the end is corrupted, padding and alphabet mismatch are the first suspects.

When to Use Base64, and When Not To

Base64 earns its place in a few concrete situations. Embedding a small image or icon directly into HTML, CSS, or a JSON payload as a data URI avoids a separate network request, which is worth it for small assets. Transmitting binary in a JSON API, where a number array of bytes would be bloated and awkward, is a legitimate use. Email attachments use base64 as part of the MIME standard, and you will encounter it wherever binary travels through text-only channels. Storing tokens or signatures as printable strings, and adding a quick layer of non-obviousness to a value that is not secret anyway, round out the common cases. For each of these, a 33 percent size cost is an acceptable trade for transport compatibility. The other direction matters just as much. Do not base64 large files when a binary channel exists, since upload endpoints and multipart forms carry bytes directly and the 33 percent overhead buys nothing. Do not base64 data to protect it, because it offers zero security; if the data is sensitive, encrypt it. For large images in the browser, prefer Blob URLs and object URLs, which avoid encoding an entire image into text. And when your goal is compact representation of binary data for humans to read, hex is often the clearer choice. Inside an application, passing binary as a Uint8Array or a Blob is more efficient than any string encoding, so base64 belongs at the transport boundary, not in every layer of your stack. The rule of thumb is simple: reach for base64 when a text-only channel forces your hand, and reach for something else the moment you have a real choice, whether that is raw binary, hex, or actual encryption. Keeping that distinction in mind prevents the two worst misuses, bloat and a false sense of security, in one stroke.

Verifying a Round-Trip and Reading Real Base64 You Meet

Before you trust any encoded output, verify the round-trip: decode the result and confirm you get back exactly what you started with. For text, the check is character-for-character, including emoji and accented letters, because those are the values that fail with non-UTF-8 tools. For binary data, decode and compare sizes; the decoded byte count must match the original. A quick inspection catches most corruption by eye: a valid base64 string uses only the alphabet characters and equals signs, has padding only at the end, and its length ignoring padding is a multiple of four. If the string contains a space, a newline, or an equals sign in the middle, it was wrapped for email or truncated, and it will not decode cleanly until the whitespace is removed. The format appears in two places you already handle every week. A data URI embeds a file directly in HTML or CSS: data:image/png;base64,iVBORw0KGgo. The base64 part after the comma is the entire file, and decoding it recovers the original bytes, which is how you rescue an image from an inline style or inspect what a payload actually contains. A JWT is the other common sighting: a JSON web token is three segments separated by dots, and each segment is base64url-encoded without padding, which is why a JWT can contain minus and underscore characters that a standard decoder rejects. Split the token on the dots and decode each segment to read the header, the payload, and the signature bytes. Recognising these shapes is most of the battle when debugging a pasted string that will not decode, because each shape tells you which alphabet and padding convention to expect before you even run the decoder.

Base64 Encode & Decode

Encode text to Base64 or decode Base64 back to readable text. Handles Unicode characters correctly.

Use the tool