Base64で日本語・Unicodeを正しく変換する方法
文字列をUTF-8のバイト列へ変換してからBase64化し、日本語や絵文字の文字化けを避ける手順を解説します。
公開日: 2026-08-10 · 更新日: 2026-08-10
Base64が表現するもの
Base64は、バイト列を限られたASCII文字で表すエンコード方式です。文字列を直接扱う仕組みではないため、日本語を変換するときは途中の文字コードを決める必要があります。
文字列 -> 文字コードでバイト列化 -> Base64文字列
Base64文字列 -> バイト列を復元 -> 同じ文字コードで文字列化
Base64は暗号化ではありません。鍵を使わず誰でも元のバイト列へ戻せるため、個人情報、パスワード、APIキーをBase64化しても保護にはなりません。
日本語や絵文字が文字化けする理由
ASCIIの文字は多くの文字コードで同じ一バイトになるため、誤った実装でも動いているように見えます。一方、日本語や絵文字は複数バイトになります。エンコード側がUTF-8、デコード側が別の文字コードを使うと、復元されたバイト列の解釈が変わり、日本語 のような文字化けが起きます。
ブラウザの古い btoa() は各入力文字を一バイトとして扱うインターフェースなので、btoa("日本語") のようにUnicode文字列を直接渡すと例外になることがあります。先にUTF-8バイト列へ変換する必要があります。
UTF-8で安全に往復する
入力 日本語 をUTF-8でエンコードすると、期待するBase64は 5pel5pys6Kqe です。絵文字 😀 なら 8J+YgA== になります。
ブラウザコードでは TextEncoder と TextDecoder を使い、文字列とUTF-8バイト列の境界を明示できます。
function bytesToBase64(bytes) {
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
function base64ToBytes(base64) {
const binary = atob(base64);
return Uint8Array.from(binary, (character) => character.charCodeAt(0));
}
const encoded = bytesToBase64(new TextEncoder().encode("日本語"));
// expected: "5pel5pys6Kqe"
const decoded = new TextDecoder("utf-8", { fatal: true }).decode(base64ToBytes(encoded));
// expected: "日本語"
fatal: true は不正なUTF-8バイト列を置換文字で隠さず例外として検出するための選択です。入力仕様が不明なデータを、必ずUTF-8だと決めつけるものではありません。送信側と受信側で文字コードを合意してください。
改行、パディング、base64url
- Base64内の改行を許すかは利用先の仕様によります。RFC 4648では、別の仕様から指示されない限りエンコーダーが勝手に改行を加えることを求めていません。
- 末尾の
=は、最後の入力ブロックを埋めるパディングです。省略できるプロトコルもありますが、受け渡し先の仕様を確認します。 - base64urlは通常のBase64の
+と/をURLで扱いやすい-と_に置き換えます。JWTの各部分などで使われます。通常のBase64と同一の文字列として扱わないでください。
改行を削除する、= を足す、文字を置換するといった修正を推測で行う前に、入力がどのBase64変種に従うかを確認します。
文字化けを切り分ける手順
- 元の文字列と、期待する文字コードを確認します。
- Base64アプリでUTF-8としてエンコードします。
- 出力をすぐデコードし、元の文字列と完全一致するか確認します。
- 日本語だけでなく、ASCII、絵文字、改行を含む小さな例でも往復を試します。
- 他システムだけで失敗する場合は、文字コード、通常のBase64かbase64urlか、パディングと改行の規則を比較します。
- 機密情報はテスト入力に使わず、
日本語😀のような無害なサンプルへ置き換えます。
App MuseumのBase64アプリは、UTF-8の文字列をブラウザ内でエンコード・デコードします。具体的な入力を往復させ、バイト列の受け渡し条件を確認するために使ってください。
参考資料
このガイドで使えるアプリ
- テキストをBase64にエンコード、またはBase64をテキストにデコード。UTF-8対応でブラウザ内処理。
関連ガイド
- JWTのheader・payload・signatureを読み解き、内容のデコードだけでは正当性を判断できない理由と安全な確認手順を解説します。開発者向けjwtjwsauthenticationsecurity