OutlookからiPhoneにメールを送ると、添付ファイル名が =?UTF-8?Q?...?= と化ける問題。長年「相性の問題」で片付けられてきたこの怪奇現象に、休日の半日を潰してトドメを刺してきました。
1. 境界線の発見:「5Nの法則」
実験の結果、ファイル名に日本語(非ASCII)が混じっている場合、ある一定の条件でエンコード方式が切り替わることが分かりました。それが以下の「5Nの法則」です。
非ASCII文字を
N 個含むとき、ASCII文字(英数字)が 5N 個に達した瞬間にiPhoneで文字化けが発生する。
| 非ASCII数 (N) | Base64限界 (ASCII) | 文字化け発動 (ASCII) |
|---|---|---|
| 1文字 (あ) | 4文字 | 5文字以上 |
| 2文字 (あい) | 9文字 | 10文字以上 |
| 3文字 (あいう) | 14文字 | 15文字以上 |
この法則はUTF-8だけでなく、欧州圏の iso-8859-1 (Latin-1) でも全く同様に発動しました。
2. なぜ「5」なのか?数学的背景
Outlookはメールヘッダーを1バイトでも節約しようと、以下の2つのエンコードを動的に使い分けています。
- MIME-B (Base64): 全体を1.33倍にする。
- MIME-Q (Quoted-Printable): 英数字はそのまま、非ASCIIを
=XX形式にする。
Latin-1の1バイト文字 Á を例にとると、Qエンコードでは =C1 (3バイト) に膨らみます。計算すると、英数字が5文字を超えたあたりで、全体をBase64で包むよりも、英数字をそのまま送れるQエンコードの方がヘッダーサイズが短くなるのです。Outlookの「ケチな最適化」がこの「5」という数字を生んでいます。
3. 犯人は誰だ?PHPによる「パケット偽装」実験
「Outlookが生成するQエンコードが悪いのか、それともiPhoneが悪いのか」を特定するため、以下の検証スクリプトを作成しました。意図的に添付ファイル名をQエンコードで送りつける「嫌がらせ」コードです。
// --- 検証用添付ファイルパート抜粋 ---
switch ($attachment_type) {
case "B": // RFC 2047 Base64
$filename_encoded = mb_encode_mimeheader($filename, "UTF-8", "B");
$head = "Content-Type: application/octet-stream; name=\"{$filename_encoded}\"\r\n";
$head .= "Content-Disposition: attachment; filename=\"{$filename_encoded}\"\r\n";
break;
case "Q": // RFC 2047 Quoted-Printable
$filename_encoded = mb_encode_mimeheader($filename, "UTF-8", "Q");
$head = "Content-Type: application/octet-stream; name=\"{$filename_encoded}\"\r\n";
$head .= "Content-Disposition: attachment; filename=\"{$filename_encoded}\"\r\n";
break;
default: // RFC 2231 (モダンな形式)
$head = "Content-Type: application/octet-stream;\r\n";
$head .= "Content-Disposition: attachment; filename*=UTF-8''" . rawurlencode($filename) . "\r\n";
}
検証結果
- To/FromヘッダーのQエンコード: iPhoneでも正常表示。
- 添付ファイル名のQエンコード: iPhoneで文字化け確定。
驚くべきことに、iPhoneはQエンコードそのものが解釈できないわけではありません。「ヘッダー(宛先など)なら読めるが、添付ファイル名の場所にあるQエンコードだけは無視する」という、極めて偏った実装をしていたのです。
4. 結論:我々が取るべき自衛策
Outlook先輩が「1バイトでも削って効率化しよう(Qを使おう)」とした善意が、iPhoneの「そこはBase64かRFC2231しか読まないよ」という偏食によって仇となる。これがこの問題の正体です。
現状、現場のエンジニアができる唯一の対策は、「英数字が5の倍数に達する前に、全角文字を1文字追加して、OutlookにBase64を強制させる」という、泥臭いファイル名ハックのみです。
もし、あなたの周りでファイル名が化けて困っている人がいたら、そっと「全角文字をもう一文字増やしてみて」と伝えてあげてください。
そして、欧州のお友達には、逆に「非ASCII文字を添付ファイル名に使わないで!」と教えてあげてください。
0 件のコメント:
コメントを投稿