データを扱う単位と末尾の=に注目しながらBase64の説明

  • 2019年4月11日
  • 2019年4月11日
  • 言語

 この記事で扱うBase64は
RFC 4648 – The Base16, Base32, and Base64 Data Encodings#section-4
で定義されている素朴なBase64です。URLセーフなものであったり、固定長で区切られたりするBase64は取り扱いません。

 Base64はオクテットデータ(8bit単位のデータのこと。現代では1byteと同義)を限られた表現空間で自由に表すために生まれた形式です。Base64形式による変換をオクテットデータに実行することで、英数字とほんの少しの記号しか使えないかつての電子メールの様な表現空間で、画像、音楽といったそのままでは表せないデータを表せるようになります。Base64は次の64文字とパディング1文字で自由にバイナリを表します。


     Value Encoding  Value Encoding  Value Encoding  Value Encoding
         0 A            17 R            34 i            51 z
         1 B            18 S            35 j            52 0
         2 C            19 T            36 k            53 1
         3 D            20 U            37 l            54 2
         4 E            21 V            38 m            55 3
         5 F            22 W            39 n            56 4
         6 G            23 X            40 o            57 5
         7 H            24 Y            41 p            58 6
         8 I            25 Z            42 q            59 7
         9 J            26 a            43 r            60 8
        10 K            27 b            44 s            61 9
        11 L            28 c            45 t            62 +
        12 M            29 d            46 u            63 /
        13 N            30 e            47 v
        14 O            31 f            48 w         (pad) =
        15 P            32 g            49 x
        16 Q            33 h            50 y

RFC 4648 – The Base16, Base32, and Base64 Data Encodings#section-4

 6bit分のバイナリパターン2^6=64種それぞれに英数字と記号を割り振ることによって、英数字と記号のみで自由にデータを表します。64文字を使うからBase”64″なわけですね。
 アルファベットの大文字26文字、小文字26文字、数字10文字、記号2文字の合わせて64文字が0個以上連なった文字列が主なデータ部になります。これは[0-9a-zA-Z+/]*で正規表現として記述できます。これの64文字を4文字ずつ使い6*4=24bit、つまり3byteずつデータを表現するのが基本です。例えば次の様になります。

8bit単位のデータを用意
01010111 00100101 11011101 01101100 01011100 01101010
↓6bitずつで区切る
010101 110010 010111 011101 011011 000101 110001 101010
↓10進数に変換
25 62 27 35 33 5 61 52
↓対応する文字に変換
Z + b j h F 9 0
↓24bitを表す4文字ずつにまとめる
Z+bj hF90

 変換過程は人間の目で整理できるように示してあります。実際はbitのまま取り扱うので実装したコードはけっこうシンプルです。
 24bitずつ8bit単位のデータを区切っているので余りが生まれます。この余りを処理するために、65文字目である=が変換後の文字列末尾に足される時があります。この=の付け足しは={0,2}で正規表現として表せます。4文字ずつ文字列を作るのに、末尾の=の数が0,1,2の3種類に限られるのは8bit単位のデータを24bitずつ文字列まとめているからです。余りなし、8bit余り、16bit余りの3種類しかないわけですね。余り0のパターンは最初の例です。余り8bitのパターンを例にすると次の様になります。

24bitずつ区切った時8bit余る8bit単位のデータを用意
01010111 00100101 11011101 01101100
↓6bitずつで区切る
010101 110010 010111 011101 011011 00
↓6bitずつで区切った時点で余っている2bitを6bitになる様4個の0で埋める
010101 110010 010111 011101 011011 000000
↓10進数に変換
25 62 27 35 33 0 
↓対応する文字に変換
Z + b j h A
↓24bitを表す4文字ずつにまとめる
Z+bj hA
↓24bitを表す4文字ずつにまとめた時余っている2文字が4文字になる様に=で埋める
Z+bj hA==

余り16bitのパターンを例にすると次の様になります。

24bitずつ区切った時16bit余る8bit単位のデータを用意
01010111 00100101 11011101 01101100 01011100
↓6bitずつで区切る
010101 110010 010111 011101 011011 000101 1100
↓6bitずつで区切った時点で余っている4bitを6bitになる様2個の0で埋める
010101 110010 010111 011101 011011 000101 110000
↓10進数に変換
25 62 27 35 33 5 48
↓対応する文字に変換
Z + b j h F w
↓24bitを表す4文字ずつにまとめる
Z+bj hFw
↓24bitを表す4文字ずつにまとめた時余っている3文字が4文字になる様に=で埋める
Z+bj hFw=

 文字列からオクテットデータの変換は逆方向に行うだけです。デコードも三種類のパターンがあるわけですね。
 どの様な8bit単位のデータでも64種の文字の連なりと1種の文字の付け足しで表せることとその変換方法がわかりました。次の正規表現はBase64形式を表現する正規表現です。

[0-9a-zA-Z+/]*={0,2}
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG