Base64 って結構カオス?

Base64 のライブラリをあまり調べたことがなかったので調べてみた。

まず、Base64 には多くの変形版が存在するという点に注意する必要がある。自分で使いたいのはどういった目的なのか、それをライブラリはサポートしているのか、のようなことだ。変形版については、Wikipedia に詳しくのっているのでそれを参照されたし。変形版は以下のような違いがある。

  1. 62 番目の文字を何とみなすか
    1. 「+」プラス
    2. 「-」マイナス
    3. 「.」ピリオド
    4. 「_」アンダースコア
    5. 「!」エクスクラメーション
  2. 63 番目の文字を何とみなすか
    1. 「/」スラッシュ
    2. 「-」マイナス
    3. 「_」アンダースコア
    4. 「:」アンダースコア
  3. パディングの有無
    1. 「=」か「なし」
  4. 1行が固定長かどうか
  5. 行の最大長
    1. 64
    2. 76
    3. 何かに依存
  6. 改行文字
    1. CRLF ( 必要な場合のみ )
    2. なし
  7. 指定された文字以外を使えるかどうか
  8. 行のチェックサム
    1. なし
    2. 24-bit CRC (Radix-64-encoded, including one pad character)

標準とされる Base64 は以下のとおり。ほとんどはこれをターゲットにしているはず。

  1. 62 番目の文字を何とみなすか
    1. 「+」プラス
  2. 63 番目の文字を何とみなすか
    1. 「/」スラッシュ
  3. パディングの有無
    1. 「=」
  4. 1行が固定長かどうか
    1. はい
  5. 行の最大長
    1. 64 or 76
  6. 改行文字
    1. CRLF ( 必要な場合のみ )
  7. 指定された文字以外を使えるかどうか
    1. 禁止
  8. 行のチェックサム
    1. なし
    2. 24-bit CRC (Radix-64-encoded, including one pad character)

ここまで見ると、Base64 のライブラリはこれらをどこまでサポートしているのかという情報があって、こういった点を指定することができて然るべきだ、と思えてくる。では、実際にライブラリやコードを見てみよう。

  • C/C++ ライブラリ
    • OpenSSL: Documents, BIO_f_base64(3)
      • 改行するかどうかを指定できる、既定ではする
        • BIO_set_flags() に BIO_FLAGS_BASE64_NO_NL を指定すると改行しないようにできる
      • 改行位置は 64
      • 改行文字は CRLF ではなく LF
      • 既知のバグがあるらしい
    • Crypto++: base64.cpp Source File
      • 改行するかどうかを指定できる、既定ではする
      • 改行位置が指定できる、既定では 72・・・72?
      • 改行文字は CRLF ではなく LF
    • hamigaki
      • 改行できない?
      • 62、63 番目の文字は、+/ か -_ のペアを使うことができる
    • b64: Base-64 Encoding Library - Synesis Software - C/C++ Software Libraries Resource Site
      • RFC 1113 に対応しているらしい
      • 62、63 番目の文字は、+/
      • 改行文字は CRLF
      • 改行位置は、64 か 76 推奨で任意に指定できる
      • ドキュメントがかなり詳細に記述されている


ここに書いた情報はドキュメントやソースコードを見ながら書いたが、間違いがあるかもしれないので注意してほしい。詳しいドキュメントがあったのは、b64 だけだった。それにしても、どれもこれも狙ったかのように仕様がまちまちである。どれも、それほど RFC に気を取られていないように思える。特に OpenSSL がこれでは、他のコードは互換性維持のために RFC を無視してそれに合わせる必要が出てくるだろう。・・・中々厄介である。b64 は、改行文字が選択できればよいのだが・・・。


というわけで、ライブラリをそのまま使うだけでは何か問題に遭遇する可能性が高いので、外部インターフェースとの連携が必要な場合は特に注意が必要だろう。どなたか、C/C++ でいいライブラリ知りませんか?


気になったので他の言語も調べてみた。

  • C/C++ 以外の言語編


他の言語も結構まちまち。汎用性という意味では、Java のが一番よさげか。


きっと Bae64 は、その原理のシンプルさからみんながばらばらと実装していってこんな感じになったんだろうな。Base64 なら、この辺を細かく制御できるコードを書けば天下とれそうだ。細かいけど。


以下は調査中に見つけたコード。面白そうだったので挙げておく。