Tools

Why Base64 Decoding Garbles Japanese Text & How to Fix It

Base64 Encoding JavaScript Troubleshooting
Conclusion

Using only atob() will not decode Japanese correctly. Reinterpreting it as UTF-8 using TextDecoder is the correct approach.

The Problem: Garbled Text with atob()

const base64Str = "44GT44KT44Gr44Gh44Gv"; // "こんにちは" (Hello)
const decoded = window.atob(base64Str);
console.log(decoded);
// -> "ã"ã‚"ã«ã¡ã¯" (Garbled)

The Cause

atob() is designed assuming 1 character = 1 byte (ASCII/Latin-1).

Since Japanese uses UTF-8 (1 character = up to 3 bytes), the byte sequence gets interpreted separately, resulting in garbled text.

atob() Assumption Japanese (UTF-8)
1 character = 1 byte 1 character = 3 bytes (Multi-byte)
Interprets raw bytes directly as characters Requires combining multiple bytes to form a single character

Code Solution

function safeBase64Decode(base64) {
  const binStr = window.atob(base64);
  const bytes = new Uint8Array(binStr.length);
  for (let i = 0; i < binStr.length; i++) {
    bytes[i] = binStr.charCodeAt(i);
  }
  return new TextDecoder('utf-8').decode(bytes);
}

console.log(safeBase64Decode("44GT44KT44Gr44Gh44Gv"));
// -> "こんにちは"

In Node.js

const decoded = Buffer.from("44GT44KT44Gr44Gh44Gv", 'base64').toString('utf-8');
console.log(decoded); // "こんにちは"
Note

For Base64URL formats (like JWT, where + -> -, / -> _, and padding is omitted), you need a preprocessing step to revert to standard Base64 before passing it to atob().

Quick Tool Check

If you want to quickly check Base64 contents before writing code, a UTF-8 compatible decoding tool is helpful.

🧪 Base64 Encode/Decode Tool

Fully supports Japanese text. A safe tool that runs entirely within the browser.

試す