tohokuaikiのチラシの裏

技術的ネタとか。

base64エンコードに関するちょっとした調査

メールのヘッダを調べてて、インターネット・プロトコル詳説(3):MIME(Multipurpose Internet Mail Extensions)〜前編 - @ITを読んでて。
いまさら感もいいところだけど、自分がわかってなかったのでメモ。

とりあえず、

バイナリ・データから3バイトずつ切り出し、これらを6ビット(10進では0から63に該当する)ごとに64種類のASCIIコードへそれぞれ割り当てていくエンコード方法のこと

ほほう。でも、

 例えば、「@IT」(シフトJIS)は、16進では次のようになる。

0x81 0x97 0x82 0x68 0x82 0x73

 そのため、Base64では次のように表現できる。

gZeCaIJz

。。。。。そのためって、そっからそこには全然直結しねぇって(苦笑)。


というわけで実験。大切なのは、MIMEが決めた変換表なのね。

itoh@colinux:~/tmp$ php -r 'echo base64_encode("a")."\n";'
YQ==
itoh@colinux:~/tmp$ php -r 'echo base64_encode("aa")."\n";'
YWE=
itoh@colinux:~/tmp$ php -r 'echo base64_encode("aaa")."\n";'
YWFh

これは、"a"が、16進数では、

itoh@colinux:~/tmp$ php -r 'echo bin2hex("a")."\n";'
61

さらに、2進数で

itoh@colinux:~/tmp$ php -r 'echo base_convert(bin2hex("a"),16, 2)."\n";'
1100001

って表示される。こうやって表示されているけれども16進数=「2進数で8桁」なので
01100001
っていう表示がより正しい。


で、これを6ビットずつに分割*1(なんで6ビットかっていうと、割り当て表が64文字までしか使ってないから)。・・・・すると、

011000 01

って1だけが端になる。そこで、ここは0でパディング

011000 010000

ってなる。
これをMIMEが決めた変換表にしたがって変換すると

YQ

ってなる。4文字ごとに変換して、残りは==でパディングするので、答えは

YQ==

ってなる。なんと"a"をエンコードしたら4倍になっちゃったよっていう。

*1:6ビットだから2*2*2*2*2*2=64でBase64っていうんだっていまさらながら気が付いた