hotmailの件名文字化けが一向に改善されないようなので、なんとか回避できないか考えてみる。
まずhotmailの挙動を調べる。
最初に件名に何文字まで入るのか調べてみた。
「1234567890123…」(半角のみ)
「1234567890123…」(全角のみ)
「12345678901234567890123…」(半角+全角)
という長い件名のテストメールを自分宛に出してみる。
自分宛に届いたメールを開く。
結果は…
文字種別 | 件名 | 文字数 |
半角のみ | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 | 100文字 |
全角のみ | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 | 100文字 |
半角+全角 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 | 100文字 |
どうやら、半角全角に関係なく、100文字が限度の様子。内部処理はUnicodeで行っていると思われる。
ちなみに、WeMail32で受信するとこうなる。
文字種別 | 件名 |
半角のみ | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 |
全角のみ | 1234567890123456789#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0 |
半角+全角 | 123456789012345678901234567890123456789012345678901234567890渦慨偽係弘駑駭34567890渦慨偽係弘駑駭駮駱駲67890 |
次に生ヘッダのSubjectを確認する。
(1)半角のみ
Subject: 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
半角のみの場合は行分割は行われないようだ。
(2)全角のみ
Subject: =?iso-2022-jp?B?GyRCIzEjMiMzIzQjNSM2IzcjOCM5IzAjMSMyIzMjNCM1IzYjNyM4Izkj?= =?iso-2022-jp?B?MCMxIzIjMyM0IzUjNiM3IzgjOSMwIzEjMiMzIzQjNSM2IzcjOCM5IzAj?= =?iso-2022-jp?B?MSMyIzMjNCM1IzYjNyM4IzkjMCMxIzIjMyM0IzUjNiM3IzgjOSMwIzEj?= =?iso-2022-jp?B?MiMzIzQjNSM2IzcjOCM5IzAjMSMyIzMjNCM1IzYjNyM4IzkjMCMxIzIj?= =?iso-2022-jp?B?MyM0IzUjNiM3IzgjOSMwIzEjMiMzIzQjNSM2IzcjOCM5IzAbKEI=?=
行頭の空白1文字を含め1行75文字となるように行分割されている。エンコーディングはJIS(iso-2022-jp)で、Bエンコーディング(base64)となるようである。
(3)半角+全角
Subject: =?iso-2022-jp?B?MTIzNDU2Nzg5MBskQiMxIzIjMyM0IzUjNiM3IzgjOSMwGyhCMTIzNDU2?= =?iso-2022-jp?B?Nzg5MBskQiMxIzIjMyM0IzUjNiM3IzgjOSMwGyhCMTIzNDU2Nzg5MBsk?= =?iso-2022-jp?B?QiMxIzIjMyM0IzUjNiM3IzgjOSMwGyhCMTIzNDU2Nzg5MBskQiMxIzIj?= =?iso-2022-jp?B?MyM0IzUjNiM3IzgjOSMwGyhCMTIzNDU2Nzg5MBskQiMxIzIjMyM0IzUj?= =?iso-2022-jp?B?NiM3IzgjOSMwGyhC?=
全角のみと同じ。
★復号
次にBエンコーディングを復号してみよう。
(2)全角のみ
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
*はESC(0x1B)。「ESC $ B」は、JISコードで2バイトコードの始まりを表し、「ESC ( B」は、2バイトコードの終わり(以降は1バイトコード)を表す。
これを見るとわかるとおり、hotmailはJISコードに変換してから行分割を行っているため、2バイトコードの状態に入ったまま改行が行われる。2行目の最後は「…#9#」で終わっているが、これは全角「0」のJISコード(0x2330 '#0')が3行目と泣き別れている。この状態のヘッダを受け取ったとき、まず行分割を解除し行結合を行ってから論理行単位でJISコードに戻す分には問題ない。
しかし、WeMail32のようなメーラーの場合、各行を物理行単位でJISコードに戻してから行結合を行う。そのため、2行目の最後の「#」(「0」の泣き別れた上位オクテット)は正しいJISコードとして識別できないため無視され、2行目は「…789」となる。
3行目は、そもそも「ESC $ B」がないため1バイトコードとして扱われるため、「0#1#2#…」と意味不明な文字が表示されることになる。3行目以下も同様である。JISコードとして解釈した結果は以下のようになる。
Subject: 1234567890123456789 0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0# 1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1# 2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2# 3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0
これを行結合すると「1234567890123456789#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0」という文字化けになる。
(3)半角+全角
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
全角のみの場合よりさらに状況はひどく、3行目と4行目の間でESCシーケンス「ESC $ B」が泣き別れている。これはひどい。
JISコードとして(無理やり)解釈するとこんな感じ。
Subject: 12345678901234567890123456 789012345678901234567890 B#1#2#3#4#5#6#7#8#9#0123456789012 3#4#5#6#7#8#9#0123456789012345 6#7#8#9#0
物理行の途中で半角/全角の境目があると、ESCシーケンスが埋め込まれるため、そこでコード認識が正常状態に復帰する。
行結合すると「12345678901234567890123456789012345678901234567890B#1#2#3#4#5#6#7#8#9#01234567890123#4#5#6#7#8#9#01234567890123456#7#8#9#0」となる。
あれ?WeMail32の表示「123456789012345678901234567890123456789012345678901234567890渦慨偽係弘駑駭34567890渦慨偽係弘駑駭駮駱駲67890」と合わない…
この辺はWeMail32側の異常系処理にも少し問題があるのかもしれない。たぶん、ESCシーケンスが泣き別れているのが影響を及ぼしているのだろう。
★で、回避できるの?
メーラーに正しくJISコードを認識させるには、物理行単位でESCシーケンスを適切に埋め込んでやる必要がある。
(2)全角のみ
まず物理行の各行のESCシーケンスを適切に埋め込むと同時に、2バイトコードの泣き別れを無くす。
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
次に物理行1行あたり75文字に収まるように行分割しなおす。base64符号化した状態で75文字なので、符号化前のJISコードレベルだと1行あたり42文字にする必要がある。
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(42文字にするために、各行末に半角空白(_)が2文字ずつ付いている)
JISコードとして解釈すると
Subject: 12345678901234567__ 89012345678901234__ 56789012345678901__ 23456789012345678__ 90123456789012345__ 678901234567890
となる。つまり、件名が全部全角であるとすれば、17文字ごとに半角空白2文字を挟めばよいことになる。例えばこんな感じ。
「12345678901234567 89012345678901234 56789012345678901 23456789012345678 90123456789012345 678901234567890」
これはWeMail32でも正しく受信できることを確認できた。
(3)半角+全角
半角と全角が混在する場合、ESCシーケンスが頻繁に現れることになるため単純にはいかない。
上の例でいくと、
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
行末を1バイトモードで終えるためには、「ESC ( B」の3バイトを行末に持ってこなければならず、そうすると4行目の行末で42文字をオーバーしてしまう。42文字で収めるために行末の2バイトコードを次の行に持っていくと、「ESC $ B ESC ( B」という全く意味のないコードができてしまう。この意味のないコードを削除すると、行末に半角空白を6文字入れなければならなくなる。
1 2 3 4 5 12345678901234567890123456789012345678901234567890
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
JISコードを適用して結合すると、「12345678901234567890123456789012345678901234567890 12345678901234567890 12345678901234567890 1234567890」となるが…
変に途中で空白が入って間延びしてるので何か変。しかもいちいちこの変換を行うのは手間に過ぎる。
でもまあ、いちおうWeMail32でも正しく認識はできた。
★結論
半角/全角混在の場合は手作業でやれば何とかなるが、単純に計算できないので、当面は
- 件名を全部全角で書く(半角は混ぜない)
- 全角17文字ごとに半角空白2文字を挿入する