第235章 base64の基礎


MIME(Multipurpose Internet Mail Extension)とは、メールにメール本文以外に ファイルとか、いろいろなものを付け加えるための規格です。 メールソフトのオプションにたいていMIMEという項目がありますが、 あれがそうです。日本語をヘッダに埋め込むのもこれを使います。 日本語の場合文字セットはISO-2022-JPを用いエンコードタイプは base64というのを用いるのが普通です。



メールのヘッダを観察するにはMicrosoft Outlook ExpressかNetscape Navigator についてくるメーラーがよいです。 メーラーの中にはヘッダ情報を見ると日本語部分がすでにS-JISに なおした状態で表示するものもあります。(この方がユーザーにとっては 親切設計ですが・・)

さて、ヘッダに日本語を埋め込むには

=?ISO-2022-JP?B?base64でエンコードしたもの?=

という形式をとります。「エンコードしたもの」のところには 必ず4の倍数個の文字(記号)が来ます。 ISO-2022-JPは小文字でiso-2022-jpと 書かれていることもあります。その次のBはbase64の意味です。 多数の観察をした結果このBを小文字のbで表しているものは みたことがありません。このへんの事情に詳しい人はたくさんいるので 興味のある人はMLなどで尋ねてみてください。

さて、具体的なエンコード方法がわからないとプログラムの書きようがありません。 base64では、次のような方法をとります。

1.エンコードしたい文字列を前から順番に3バイトずつ区切ります。 2.これを今度は前から順に6ビットずつ区切りなおします。 3.この6ビットの値に応じてA-Z, a-z, 0-9, +,/の文字に置き換えます。

たったこれだけです。

うーーー、これではよくわからん!!という方のためにもう少し詳しく説明します。 たとえば「田中君」という6バイトの日本語をエンコードしたいと思います。

1.各漢字のJISコードを調べる 2.2進法で表す 3.前から6けたずつ区切る 4.16進(10進でもいいですが)になおす 5.それぞれの数値に対応する記号(A-Z, a-z, +, /)になおす

いうことになります。

「田」JISで0x4544

「中」JISで0x4366

「君」JISで0x372F

これを16進法で1バイトずつ横1列に表示すると

(45)(44)(43)(66)(37)(2F)

となります。これを2進法で表すと

(01000101)(01000100)(01000011)(01100110)(00110111)(00101111)

となります。これを先頭から6ビットずつ切り直します。

(010001)(010100)(010001)(000011)(011001)(100011)(011100)(101111)

これではわかりづらいので各組を16進に戻します。

(11)(14)(11)(3)(19)(23)(1c)(2f)

となります。2進と16進の変換はWindowsにおまけで付いている 電卓を使うと簡単です。

これを記号に置き換えます。 あらかじめ表でも作っておくと楽です。

縦H横L0123456 789ABCDEF
0 ABCDEFGH IJKLMNOP
1 QRSTUVWX YZabcdef
2 ghijklmn opqrstuv
3 wxyz0123 456789+/

6ビットの値なので2の6乗=64で64種類の記号で表すことができます。 (それでbase64という)

先ほどの6ビット値を上の記号表で置き換えると

(R)(U)(R)(D)(Z)(j)(c)(v)

さて、JISでは2バイト文字の始まりの合図として(0x1b, 0x24, 0x42) の3バイトを付けなくてはなりません。うまい具合に3バイトなので 4つの記号にエンコードされます。同様の手順でエンコードすると

GyRC

また、2バイト文字の後にはASCII文字が来るので(0x1b, 0x28, 0x42) を付け加えます。これをエンコードすると

GyhC

となります。

これをヘッダに埋め込むには

=?ISO-2022-JP?B?GyRCRURDZjcvGyhC?=

とすればよいことになります。 これが本当に正しく「田中君」と解釈されるかどうか 実験するには、自分で自分にメールを出します。 この時の件名に上のエンコードされた文字列を使います。 自分に届いたメールの件名が「田中君」となっていれば 成功です。

さて、この例題ではエンコードする本文が6バイトで 3の倍数になっていました。では、3の倍数でないときは どうすればよいのでしょうか。

「田」だけを変換したい場合はどうすればよいのでしょうか。

「田」JISで0x4544

(1b,24,42)(45)(44)(1b,28,42)

(00011011)(00100100)(01000010)(01000101)(01000100)(00011011)(00101000)(01000010)

(000110)(110010)(010001)(000010)(010001)(010100)(010000)(011011)(001010)(000100)(0010**)

最後の6ビットの下2桁が困ります。 こういう場合は下2桁を0で埋めます。また、全体としてこれを記号に直すと 11個となり4の倍数になりません。この場合1個の「=」を付け加えます。

これを16進化して記号にすると

6, 32, 11, 2, 11, 14, 10, 1B, A, 4, 8

G, y, R, C, R, U, Q, b, K, F, I

4の倍数とするため最後に「=」を付け加えて

=?ISO-2022-JP?B?GyRCRUQbKFI=?=

となります。

さて、メールのヘッダを観察しているとサブジェクトにいきなり JISコードを書いているものを見かけます。筆者のところにも 定期的にホーム・ページ情報のサービスメールが届きますが これがこのパターンです。現在のところ特に問題はありませんが 本当はかなりまずいことです。

また、古いメールを観察するとISO-2022-JPのQというのがたまに 見つかります。これは、Quoted-printableと呼ばれるもので最近では ほとんど見かけません(少なくとも筆者のところでは)。

さて、これらの規則を理解したところでこれをプログラムにしなくてはいけません。 ちょっと面倒くさいです。次回から少しずつやっていきましょう。


[SDK第3部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 19/Oct/1999 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。