2026-03-08

今日こそ終止符!iPhoneの標準メーラーで添付ファイル名が文字化けする原因とその対応

OutlookからiPhoneにメールを送ると、添付ファイル名が =?UTF-8?Q?...?= と化ける問題。長年「相性の問題」で片付けられてきたこの怪奇現象に、休日の半日を潰してトドメを刺してきました。

1. 境界線の発見:「5Nの法則」

実験の結果、ファイル名に日本語(非ASCII)が混じっている場合、ある一定の条件でエンコード方式が切り替わることが分かりました。それが以下の「5Nの法則」です。

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 件のコメント:

コメントを投稿

綺麗に見せることに全振りした操法大会の訓練を50日間するよりも、月1回でいいから基本的な操作方法の訓練を実施すべきだと思うのは俺だけか

 7月に県の消防操法大会がある。 市内分団の持ち回り制で、今年はうちの分団が出場する。 俺も前回回ってきたときに、選手として出た。 訓練が5月から始まっている。 週5日。 訓練時間は2時間だけど、その前に準備する時間もあり、訓練後の撤収時間も必要だから、拘束時間は約3時間。 俺が...