レッスン 3
パディングと長さ
末尾の `=` が現れる理由と、長さと入力バイトの関係。
Base64 の出力長は、6 ビットグループ化を理解すれば予測できます。パディング文字(=、場合によっては ==)は「最後のセクステットは 3 バイト未満から合成された」ことを伝えます — 魔法ではなく、単なる簿記です。
パディングが現れる条件
入力長を 3 で割った余りがすべてを決めます。
入力バイト % 3 | 必要なパディング |
|---|---|
0 | なし |
1 | == |
2 | = |
理由? 各出力量子は 3 バイト ⇒ 4 Base64 記号をエンコード。不完全な量子でも 4 記号を出力しますが、実ビットを超える末尾セクステットはパディングで印され、デコーダーが正しく切り詰めます。
パディングを省略しても動くように見えることがあります — ツールが推測するから — しかし一方が = を積極的に切り、他方が正規形を要求すると、言語間 API は壊れます。
= がないもの
= は古典的 Base64 では 64 記号 payload アルファベットの一部ではない — メタ文字フィラーです。デコーダーは長さ信号として厳密に解釈するか破棄します。誤編集(URL 連結ミス、コピー/ペースト切り詰め)で静かに出力長チェックが壊れます。
ライブラリは不正なパディングパターン(equals の位置がおかしい、equals 後のゴミ)を推測せず拒否すべきです。
ビット数のメンタルモデル
- 3 オクテットごとに 4 アルファベット記号。
- 余分な 1 バイト? それでも 4 記号を出力。うち 2 つがパディング意味論を担う。
- 余分 2 バイトで
=が 1 つ。残り 1 バイトだけなら==。
剰余表を見る方が、ビット表を暗記するよりデバッグに効きます。
改行と MIME
歴史的なメールエンコーダーは古い端末向けに 約 76 文字ごとに改行を挿入しました。素の Base64 API は改行なしが多い。PEM ブロックは意図的に固定列幅で折り返します。
デコード前に \n/\r を除去せず行を連結すると、厳格なデコーダーは失敗します。逆に、パーサーがどこでも空白を無視する場合も — スタックの方針を知ってください。
形の例(概念的のみ)
ASCII 1 文字 a(0x61)をエンコードすると、標準エンコーディングでは == で終わる 4 印字文字 — ライブラリのドキュメントで文字列を確認する価値があります。
URL を「最適化」するためにパディングを手編集しない — URL-safe 方言は明示的に標準化された場合のみ =-less 形式を許容(次のレッスン参照)。
セキュリティ敏感なコードでの長さチェック
Base64 暗号文や署名を比較するとき、正規化後の長さ不一致は次を示します。
- 切り詰めバグ
- 二重エンコードミス
- クエリ文字列でのクライアント側切り詰め
Base64 payload は不透明な文字列 + 厳格検証として扱いましょう。
要点
パディングは、残り 24 ビット未満でも 4 出力記号を処理チャンクごとに出す Base64 の規則から生じます。API が要求するときは正規パディングを尊重し — 民間伝承ではなく文書化ルールに従って空白を除去/正規化してください。