Base64 文字列を検証する方法
- 文字列を チェックする Base64 に貼り付けます。改行、PEM の囲み行、
data:プレフィックスは残したままでかまいません。それらは検出事項として報告され、残りの部分も通常どおり解析されます。 - 上部の判定を読みます。問題はそれぞれ位置付きで表示されます。たとえば「3 行目、17 列目(169 文字目)」のようにです。
- 入力内容(問題箇所をハイライト) で、問題のある文字がその場所でマークされているのを確認します。
- どの Base64 バリアントに適合するか で、標準、パディングなし、URLセーフ、MIME、PEM のそれぞれの Base64 として有効か、無効ならその理由を確認します。
- 修復する を押すと 修復モード に切り替わり、文字列を整えます。
検証ツールがチェックする内容
- アルファベット外の文字。 Unicode のコードポイント付きで表示するので、ノーブレークスペース(U+00A0)やゼロ幅スペース(U+200B)のような目に見えない文字もわかります。
- アルファベットの混在。 標準 Base64 の
+と/と、Base64URL の-と_が 1 つの文字列に共存している状態です。 - 途中にある
=。 ほぼ間違いなく、2 つのエンコード済みの値がくっついています。 - ありえない長さ。 パディングを除いた長さを 4 で割った余りが 1 になるものは、どのエンコーダーからも生まれません。1 文字足りないか多いかです。
- パディング。 不足、過剰、データの長さとの不一致です。
- 最後の文字の 非正規の末尾ビット(RFC 4648 §3.5)。
- 空白と折り返し。 スペースやタブ、行の幅、行末が CRLF か LF か混在かを調べます。
詳細 には、長さ、長さ mod 4、パディングの状態、アルファベット、デコード後のサイズ、推定される内容の種類が加わります。ハイライト表示する入力のコピーは先頭 20,000 文字までですが、解析は常に文字列全体を対象にします。
同じ文字列でもデコーダーで結果が違う
「有効」かどうかは、誰に尋ねるかで変わります。次の 5 つの文字列を、よく使われる 4 つのデコーダー(Python 3.13、Node.js 24、WHATWG の atob、GNU coreutils 9.7)に通しました。
| 入力 | 問題 | Python b64decode(s, validate=True) | Node Buffer.from(s, "base64") | atob(s) | base64 -d |
|---|---|---|---|---|---|
SGVsbG8gd29ybGQ | = の不足 | エラー | Hello world | Hello world | Hello world |
SGVsbG9= | 最後の文字が非正規 | Hello | Hello | Hello | エラー |
SGVsbG8=V29ybGQ= | 2 つの値の連結 | エラー | Hello(残りは捨てられる) | エラー | HelloWorld |
SGVsbG8gd | 余り 1 | エラー | Hello | エラー | エラー |
SGVs bG8= | スペース | エラー | Hello | Hello | エラー |
危険なのは、連結された入力に対して Node が黙って Hello を返し、エラーもなくデータの半分を失うセルです。そのためこのツールは、手元のデコーダーが許容するものも含めて、すべての逸脱を報告します。そのうえでバリアントの表が、文字列がどの厳密な形式を満たすかを示します。
有効な文字列は本当に Base64 なのか
abcd、test、1234 はどれも有効な Base64 で、それぞれランダムに見える 3 バイトにデコードされます。そこでこのツールは 本当に Base64 か という問いにも、0~100 のスコアとその根拠で答えます。根拠はそれぞれ、Base64 である方向か、そうでない方向かが示されます。
- Base64 らしい根拠:正しいパディング、大文字・小文字・数字の混在、文字の多様性の高さ、
eyJでの開始({"の Base64 で、JSON や JWT に典型的)、既知のファイル形式や読めるテキストにデコードされること。 - Base64 らしくない根拠:英字のみ(単語の可能性)、16進数の数字のみ(16進数文字列の可能性)、数字のみ(おそらく数値)、大文字または小文字のみ、ごく短い文字列。
スコアはヒントとして扱ってください。これはヒューリスティックで、短い文字列ではどちらの方向にも誤ることがあります。
コードで Base64 をチェックする
実用上最も厳密なテストは往復変換です。デコードし、再エンコードして比較します。これだけで空白、パディング不足、非正規の末尾をまとめて拒否できます。
import base64
def is_canonical_base64(s):
try:
return base64.b64encode(base64.b64decode(s, validate=True)).decode() == s
except ValueError:
return False
Node.js なら同じ考え方で Buffer.from(s, "base64").toString("base64") === s と書けます。^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$ のような正規表現はアルファベットと長さをチェックしますが、SGVsbG9= や空文字列も受け入れてしまいます。URLセーフの文字列は、先に変換するか対応するアルファベットを使ってください。Base64 と Base64URL の違い を参照してください。言語ごとのエラーメッセージは Base64 のエラー にまとめています。
よくある質問
文字列が Base64 かどうかを見分けるには?
厳密には、A–Z、a–z、0–9、+、/ だけを使い、長さが 4 の倍数で、末尾の = が 2 個以下なら有効な標準 Base64 です。ただし普通の単語の多くもこの条件を満たすので、このツールは文字列の見た目とデコード結果に基づく 0~100 のスコアも表示します。
ある言語ではデコードできる Base64 が、別の言語では失敗するのはなぜですか?
デコーダーによって厳しさが違うからです。Node の Buffer.from はほぼ何でも受け付け、Python の b64decode(s, validate=True) はパディング不足を拒否し、GNU の base64 -d は非正規の最後の文字を拒否します。上の表では、同じ 5 つの文字列を 4 つのデコーダーで比べています。
非正規の Base64 とは何ですか?
最後の文字には使われないビットがいくつかあり、本来は 0 であるべきです。SGVsbG8= と SGVsbG9= はどちらも Hello にデコードされますが、正規なのは前者だけです。RFC 4648 は後者をデコーダーが拒否することを認めており、再エンコードしても後者が再現されることはありません。
有効な Base64 文字列なら、デコードしても安全ですか?
有効かどうかは中身について何も語りません。詳細 セクションにはデコード後のサイズと推定される内容の種類が表示され、対応するデコーダーへのリンクもあるので、保存する前にテキストなのか画像なのか、それ以外なのかがわかります。