Base64パディング(=)の仕組み

Base64でパディング文字=が使われる理由とは?パディングの仕組み、必要な場面と省略可能な場面、デコードの正確性への影響を詳しく解説します。

Concept

詳細な説明

Base64は入力を3バイト(24ビット)のグループで処理し、各グループから4つのBase64文字を生成します。では、入力の長さが3の倍数でない場合はどうなるのでしょうか?ここでパディングが登場します。

パディングの仕組み:

  • 入力のバイト数が3で割り切れる場合:パディング不要。例:"ABC"(3バイト)は "QUJD"(4文字、= なし)にエンコードされます。
  • 余りが1バイトの場合:エンコーダーは2つのBase64文字を生成し、== を追加。例:"A"(1バイト)は "QQ==" にエンコードされます。
  • 余りが2バイトの場合:エンコーダーは3つのBase64文字を生成し、= を追加。例:"AB"(2バイト)は "QUI=" にエンコードされます。

= 文字はBase64アルファベットの一部ではありません。デコーダーに最後のグループから何バイト破棄すべきかを伝える純粋なシグナルです。

パディングが存在する理由: パディングにより、すべてのBase64文字列の長さが4の倍数になります。これは初期の実装で固定サイズブロックでBase64を処理する際に重要でした。複数のBase64文字列を曖昧さなく連結できるようにするためです。パディングされた2つのBase64文字列を連結すれば、デコーダーは混乱なく順次処理できます。

パディングは省略できるか? はい、多くの現代的なコンテキストでは可能です。デコーダーは文字列の長さから期待されるパディングを算出できます:length % 4 == 2 なら == を追加、length % 4 == 3 なら = を追加、length % 4 == 0 ならパディング不要(length % 4 == 1 は常に無効)。

JSON Web Token(JWT)は常にパディングを省略します。多くのURL-safe Base64実装も同様です。ただし、ブラウザの atob() を含む一部の厳密なデコーダーはパディングを必要とし、パディングなしではエラーを投げます。

実践的なアドバイス:

  • エンコード時:消費側のシステムが明示的に省略を期待しない限り、パディングを含めましょう。
  • デコード時:パディングが欠けている場合に追加できるよう準備しておきましょう。シンプルなワンライナーで対処できます:
function addPadding(base64) {
  return base64 + "=".repeat((4 - base64.length % 4) % 4);
}

よくある間違い: = をエンコードされたデータの一部として扱うこと。パディングはエンコード処理に関するメタデータであり、入力バイトの表現ではありません。

ユースケース

フロントエンドライブラリがエンコード時にパディングを除去するが、バックエンドのデコーダーがパディングを必要とする場合に発生するJWTパースエラーのデバッグに役立ちます。

試してみる — Base64 Encoder

フルツールを開く