●概要
受信したメールのヘッダを見ると[例-1]の様にサブジェクトが
「Subject: =?ISO-2022-JP?B?GyRCJCIkJCQmJCgkKiMxIzIjMyM0IzUbKEo=?=」
と訳の分からないアルファベットになってしまっています。
これは、日本語文字のサブジェクトをBase64というエンコード方式で文字変換しているから起きるのです。よく、メールのタイトル(Subject)には半角英数字(ASCII互換の1バイト文字)を使うこと、という話を耳にしたことはありませんか?
インターネットは基本的に2バイト文字を受け付けないため、わざわざこのエンコード方式を使ってに半角英数字(ASCII互換の1バイト文字)に変換しているのです。
[例-1]-----------------------------------------------------------------
X-Mailer: Microsoft Outlook Express for Macintosh - 4.01 (295)
Date: Wed, 09 Dec 1998 02:29:44 +0900
Subject: =?ISO-2022-JP?B?GyRCJCIkJCQmJCgkKiMxIzIjMyM0IzUbKEo=?=
From: "Kiyotaka Murayama"
To: murayama@kipwmi.com
Mime-version: 1.0
X-Priority: 3
Content-type: text/plain; charset="ISO-2022-JP"
Content-transfer-encoding: 7bit
Status:
あいうえお12345
----------------------------------------------------------------------
では、なぜ、このSubjectを元の正しい日本語にする必要があるのでしょうか?
普段皆さんがお使いのメールソフトは自動的にこの文字変換を行い、ちゃんと正しい日本語に変換してくれます。メールソフトだけを使ってメール管理を行っていれば特に必要の無いことかもしれません。
しかし、過去のメールをデータベース(ここにファイルメーカーが登場します。)にインポートし、管理したい場合には、どうしてもサブジェクトを日本語に戻したいと思われる方も多いと思います。
ISO-2022-JP(インターネットでいうJISコードのこと)ファイルはお手持ちにのテキストエディタでシフトJIS変換を指定して開けばちゃんと日本語に変換してくれますが、サブジェクト(正確にはメールヘッダ部分)は前述の訳の分からないアルファベットのままです。
●Base64のデコード方法
サブジェクトの文字
ここでは「Subject: =?ISO-2022-JP?B?GyRCJCIkJCQmJCgkKiMxIzIjMyM0IzUbKEo=?=」として話を進めます。
このサブジェクトの文字列から「?ISO-2022-JP?B?」 の文字列の次のから 「?=」 までの間の文字列を切り取ります。
つまり、GyRCJCIkJCQmJCgkKiMxIzIjMyM0IzUbKEo= ということになります。
次に、各文字を2進数表記(6ビット単位)に変換します。
その際使うのが RFC 2045の Table 1 です。(一番下にある表を参照してください)
つまり、左から順に
右へ→
文字 Decoding 6ビット
単位文字 Decoding 6ビット
単位文字 Decoding 6ビット
単位文字 Decoding 6ビット
単位↓左下に続く
G 6 000110 y 50 110010 R 17 010001 C 2 000010 ↓左下に続く
J 9 001001 C 2 000010 I 8 001000 k 36 100100 ↓左下に続く
J 9 001001 C 2 000010 Q 16 010000 m 38 100110 ↓左下に続く
J 9 001001 C 2 000010 g 32 100000 k 36 100100 ↓左下に続く
K 10 001010 i 34 100010 M 12 001100 x 49 110001 ↓左下に続く
I 8 001000 z 51 110011 I 8 001000 j 35 100011 ↓左下に続く
M 12 001100 y 50 110010 M 12 001100 0 52 110100 ↓左下に続く
I 8 001000 z 51 110011 U 20 010100 b 27 011011 ↓左下に続く
K 10 001010 E 4 000100 o 40 101000 = (pad)
と変換します。
次に、この2進文字列(6ビット単位)を8ビット単位でまとめます。右へ→
00011011
00100100
01000010
↓左下に続く
00100100
00100010
00100100
↓左下に続く
00100100
00100100
00100110
↓左下に続く
00100100
00101000
00100100
↓左下に続く
00101010
00100011
00110001
↓左下に続く
00100011
00110010
00100011
↓左下に続く
00110011
00100011
00110100
↓左下に続く
00100011
00110101
00011011
↓左下に続く
00101000
01001010
00=
(pad)
と変換します。
次に、この8ビット単位の2進数をASCIIコードに変換します。
これで、ISO-2022-JPコードに変換できました。右へ→
00011011
ESC00100100
$01000010
B↓左下に続く
00100100
$00100010
"00100100
$↓左下に続く
00100100
$00100100
$00100110
&↓左下に続く
00100100
$00101000
(00100100
$↓左下に続く
00101010
*00100011
#00110001
1↓左下に続く
00100011
#00110010
200100011
#↓左下に続く
00110011
300100011
#00110100
4↓左下に続く
00100011
#00110101
500011011
ESC↓左下に続く
00101000
(01001010
J00
=(pad)
これらの文字をつなげて文字列とすると
ESC$B$"$$$&$($*#1#2#3#4#5ESC(J
となります。
注意、ESCは1バイト文字で16進表記の 1B を示します。つまり、エスケープシーケンスのことです。
この文字列をシフトJISに変換すると
あいうえお12345
となり、やっと読める文字になりました。
お疲れさまでした。
●最後に
大ざっぱな説明ですが、明らかな間違いや補足事項がありましたらご指摘いただければ幸いです。
RFC 2045 Internet Message Bodies November 1996
Table 1: The Base64 Alphabet
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