Blog · How-To

Base64 to Text: Decode Back to a Readable String

Convert Base64 strings back to readable text. Fix garbled output, handle non-ASCII characters, and avoid the encoding mistakes that turn your decoded text into garbage.

You paste a Base64 string into a decoder and the output is a mess. Question marks where letters should be. Gibberish symbols. Or worse — it looks fine at first glance but the non-English characters are silently corrupted. Converting Base64 to text is simple in theory but the character encoding layer trips people up constantly. Here is how to get readable output every time.

In short: Base64 decodes to bytes, not text. To get readable output, those bytes must then be interpreted using the correct character encoding — UTF-8 in 99% of cases. If your decoded text is garbled, the problem is almost always an encoding mismatch, not the Base64 decode itself. Use our Base64 encoder/decoder to skip the hassle — it auto-detects UTF-8 and handles the encoding layer for you.

Step 1: Decode the Base64 String

The decode step itself is deterministic. The same Base64 input always produces the same byte sequence. Here are the three most common ways to get those bytes:

// JavaScript
const decoded = atob("SGVsbG8="); // → "Hello"

# Python
import base64
decoded = base64.b64decode("SGVsbG8=").decode("utf-8") # → "Hello"

# Command line
echo "SGVsbG8=" | base64 -d # → Hello

This part works for ASCII text 100% of the time. If your input is plain English letters, numbers, and symbols, you are done. But if the original text contained anything beyond basic ASCII — accented letters, emojis, Chinese characters, curly quotes — this naive decode will produce corrupted output. Read on.

Step 2: Fix the Character Encoding (Why Your Output Is Garbled)

Base64 encodes bytes, and text is stored as bytes using a character encoding. If the original text was UTF-8 but you interpret the decoded bytes as Latin-1, every non-ASCII character turns into garbage. The fix depends on what tool you are using:

In JavaScript: atob() only handles Latin-1. For any text beyond ASCII, you need the TextDecoder approach:

function base64ToText(b64) {
  const binary = atob(b64);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return new TextDecoder("utf-8").decode(bytes);
}

base64ToText("Q2Fmw6k="); // → "Café"

In Python: The .decode("utf-8") at the end of the chain is what turns bytes into a string. If you omit it, you get a bytes object instead of a str. If your output looks like b'Hello' instead of Hello, that is the missing .decode().

Use the Online Tool (Skip Both Steps Entirely)

If you want the decoded text and do not care about the plumbing: paste your Base64 string into the decoder on base64go.com. The tool handles the byte→text conversion automatically, detects whether the output is valid UTF-8, and shows you the result immediately. No TextDecoder boilerplate, no encoding guesswork. For a broader look at decoding methods beyond text specifically, see our complete Base64 decoding guide.

When Decoded Text Still Looks Wrong

Sometimes the encode-decode round trip produces readable-but-wrong output: the text is valid characters but not the characters you expected. Three common causes:

  • The original encoding was not UTF-8. Windows applications sometimes use UTF-16 LE or Windows-1252. If your decoded text alternates between readable letters and blank/null characters, it was probably UTF-16. If accented characters are systematically swapped with other accented characters, it was probably Windows-1252. Try .decode("utf-16-le") or .decode("cp1252") in Python.
  • The Base64 includes a Data URI prefix. If your string starts with data:text/plain;base64,, that prefix is part of the string, not part of the encoded data. Strip it before decoding or the output will have 20+ bytes of garbage at the start.
  • The Base64 string is truncated. If the string is missing trailing characters, the last 1-2 bytes of decoded output will be corrupted. A valid Base64 string always has a length that is a multiple of 4.

Frequently Asked Questions

Why is my decoded Base64 text showing as random symbols?

The bytes decoded correctly but the character encoding is wrong. If you used atob() in JavaScript, it only handles Latin-1 — anything beyond ASCII breaks. Use TextDecoder("utf-8") instead. In Python, make sure you call .decode("utf-8") on the bytes output.

Can Base64 decode to ASCII-only text?

Base64 itself can encode any binary data, and ASCII is a subset of that. If the original text was pure ASCII, the decoded output will be too. But Base64 does not restrict or guarantee ASCII — it is completely encoding-agnostic. The output is whatever bytes were originally encoded.

How much larger is Base64 than the original text?

Exactly 33% larger. Every 3 bytes of original text become 4 Base64 characters, plus padding. So a 90-character UTF-8 string becomes a 120-character Base64 string (plus possible = padding). For a deeper dive into the math, see our Base64 translator guide.

Decode Base64 to text now. No encoding headaches.

Paste your string and get readable text instantly. UTF-8 auto-detection built in.

Open Base64 Decoder