文字化けな話ばっかりしてるような気がしますが
実はメールもやってます
Postfix辞典 (2006)
Software Design
今回はメールの話
NSEG #101
2018/06/30
とみたまさひろ
その昔メールは7bitデータだった
ASCII文字しか送れなかった
ISO-2022-JPは7bit
ISO-2022-JPで日本語を使えた
今でもメールでISO-2022-JPが
使われてるのはその名残り
(もう世の中Unicodeなのに…)
でも日本語が書けるのは本文だけ
メールのヘッダにはISO-2022-JPは書けない
Subjectには書けるけど、From や To には書けない
From: "display name" <local@domain.name>
「"
」で括ればだいたいのASCII文字は書けるんだけど
ISO-2022-JPは「"
」を含んでる
「@
」「<
」「>
」も含んでる
柊明治
: ^[$BI"L@<#^[(B
メールヘッダに日本語を書けなかったから
メール本文の冒頭で名乗る文化が
生まれたんじゃないかなぁ
(個人の感想です)
Multipurpose Internet Mail Extensions
RFC 2045-2049
ヘッダ部で非ASCII文字
添付ファイル(マルチパート)
Content-Type で文字コードを指定
Content-Type: text/plain; charset=ISO-2022-JP
Charset指定と本文のエンコーディングが異なる
Content-Type: text/plain; charset=ISO-2022-JP
なぜか本文はSHIFT_JIS
文字化け!
Charset指定が無い
Content-Type: text/plain
ASCIIのはずだけど日本語
文字化け!
Subjectが生ISO-2022-JP
Subject: ^[$B%"%a%s%\@V$$$J$"$$$&$($*^[(B
MIME以前
本来ISO-2022-JPは次の文字を含まない
ISO-2022-JPと名乗っているけど
みんなが使ってるのは別のエンコーディング
ISO-2022-JPを信じると…
文字化け!
Charset変換
メール上のcharset | 実際のエンコーディング |
---|---|
ISO-2022-JP | CP50221 |
SHIFT_JIS | CP932 (Windows-31J) |
EUC-JP | CP50932 |
GB2312 | GBK |
非ASCII文字をエンコード
=?charset?B?Base64化文字列?=
=?charset?Q?abc=E3=81=82?=
「MIMEヘッダエンコーディングは複雑すぎてつらい
」
↓
Subject: =?utf-8?b?TUlNReODmOODg+ODgOOCqOODs+OCs+ODvOODh+OCo+ODs+OCsOOBr+ikh+mbkeOBmeOBjuOBpuOBpOOCieOBhA==?=
長い
encoded-wordは75バイト以下 (RFC5322)
空白があれば折り返せるけど空白がない
むりやり折り返しちゃだめ
Subject: =?utf-8?b?TUlNReODmOODg+ODgOOCqOODs+OCs+ODvOODh+OCo+ODs+
OCsOOBr+ikh+mbkeOBmeOBjuOBpuOBpOOCieOBhA==?=
文字化け!
複数のencoded-wordとして分割
Subject: =?utf-8?b?TUlNReODmOODg+ODgOOCqOODs+OCs+ODvOODh+OCo+OD?=
=?utf-8?b?s+OCsOOBr+ikh+mbkeOBmeOBjuOBpuOBpOOCieOBhA==?=
でもこれでも
文字化け!
文字を分割しちゃだめ (RFC2047)
=?utf-8?b?TUlNReODmOODg+ODgOOCqOODs+OCs+ODvOODh+OCo+OD?=
↓
MIMEヘッダエンコーディ
+ E3 83
=?utf-8?b?s+OCsOOBr+ikh+mbkeOBmeOBjuOBpuOBpOOCieOBhA==?=
↓
B3 + グは複雑すぎてつらい
正しい
Subject: =?utf-8?b?TUlNReODmOODg+ODgOOCqOODs+OCs+ODvOODh+OCow==?=
=?utf-8?b?44Oz44Kw44Gv6KSH6ZuR44GZ44GO44Gm44Gk44KJ44GE?=
ASCIIと日本語混在
MIME =?utf-8?b?44OY44OD44OA44Ko44Oz44Kz44O844OH44Kj44Oz44Kw?=
↓
MIME ヘッダエンコーディング
空白が入る
隣り合ったencoded-wordの間の空白は詰められる
くっつけちゃダメ
MIME=?utf-8?b?44OY44OD44OA44Ko44Oz44Kz44O844OH44Kj44Oz44Kw?=
繋がってる場合はASCIIも含めてエンコーディング
"
で括ってもダメ
"MIME =?utf-8?b?44OY44OD44OA44Ko44Oz44Kz44O844OH44Kj44Oz44Kw?="
"
で括られた文字列はencoded-wordではない (RFC2047)
ISO-2022-JPはさらに複雑
ISO-2022-JPはエスケープシーケンスで
複数の文字集合を切り替え
エスケープシーケンス | 文字集合 |
---|---|
ESC ( B | ASCII |
ESC ( J | JIS X 0201 ラテン文字 |
ESC $ @ | JIS X 0208-1978 |
ESC $ B | JIS X 0208-1983 |
encoded-wordはASCIIで始まり
ASCIIで終わらないとダメ (RFC2047)
ASCIIに戻すには 1B 28 42 の3バイト必要
75バイトに納める処理が複雑
ちゃんとやらないと
文字化け!
MIME後も添付ファイル名に非ASCIIは使えなかった
MIMEのファイル名
Content-Type: application/octet-stream;
name=filename.ext
name=
の値には =
, ?
が使えない (RFC2045)
つまりencoded-wordが使えない
"
で括れば =
, ?
も使えるんだけど
"
で括るとencoded-wordとみなされない (RFC2047)
…はずなんだけど、結構そういう実装ある
Content-Type: application/octet-stream;
name="=?UTF-8?B?44G744GSLnhscw==?="
文字化けしない
ホントはダメ
RFC2231 で可能に
Content-Type: application/octet-stream;
name*=utf-8''%E3%81%BB%E3%81%92.xls
MIMEヘッダエンコーディングとはまた別の方式
古い規格に矛盾しないように拡張を重ねてきた
だけど…
RFC6530 | Overview and Framework for Internationalized Email |
RFC6531 | SMTP Extension for Internationalized Email |
RFC6532 | Internationalized Email Headers |
RFC6533 | Internationalized Delivery Status and Disposition Notifications |
メールアドレスとかメールヘッダにUTF-8文字が
そのまま使える
RFCは2012年発行
どれくらい普及してるんだろう
一度ちゃんとRFC読んでみないとなー
おわり