Outlook で Unicode (UTF-8) を使うときのお話として聞いてね。
あ、良かったらこちらもどうぞ
【Outlookで自動改行させないための設定 ~もういい加減 UTF-8 / base64 でよくね?~】
https://chibitcpu.blogspot.com/2025/12/outlook.html
RFCも絡めてまとめてみたので、サクッと対応したい人はこちら
【今日こそ終止符!iPhoneの標準メーラーで添付ファイル名が文字化けする原因とその対策】
https://chibitcpu.blogspot.com/2026/03/outlook-iphone-filename-encoding-5n.html
さて・・・
iPhoneの標準メーラーで添付ファイル名が文字化けした。(正確には「復号してくれなかった」)
=?utf-8?Q?....
今までと同じ方法でファイルを添付して送っていたのに、なぜか表示されない。
そこで、表示できるときとできないときの違いを知りたくて、メールのソースを表示してみた。
すると
■ 表示できる方
filename="=?utf-8?B?..."
■ 表示できない方
filename="=?utf-8?Q?..."
できる方は 「B」エンコーディング (Base64)、できない方は 「Q」エンコーディング (Quoted-Printable っぽいやつ) だった。
おいおい、なんで違うんだよって思って、Copilotに聞いてみた。
Q. Outlook2019を使っています。ファイル名に日本語を含む添付ファイルを送るとき、ファイル名が「B」エンコーディングされるときと、「Q」エンコーディングされるときがあります。「B」エンコーディングで固定したいのですが、どうすればいいですか?
A. 結論から言うと、Outlook 2019 では添付ファイル名の符号化方式をユーザー側で固定する設定は存在しません。これは仕様であり、Outlook が内部ロジックに基づいて自動的に選択しているためです。ただし、どのような条件で 「B」/「Q」が選ばれるのかは不明です。ただ 、「B」エンコーディング に“寄せる”ために現実的にできる対策があります。
まじかよ。仕様かよ。
Base64に「寄せるため」には、日本語を多めにしろだって。
【2026.3.3 】
Outlookのエンコード仕様を確認したくて、ファイル名を変えながら添付して送って調べてみた。
漢字1文字(3バイト):半角5文字(5バイト)以上の比率だと「Q」エンコーディング 、未満だと「B」エンコーディングだった。
Quoted-Printableより、Base64の方が短い(エンコード後のバイト数が少ない)んだけど…なんでだろ
【2026.3.4 その1】
おもしろそう。あとで読もうっと。
【2026.3.4 その2】
おぉ、そういうことか。日本人にしてみたら謎の(Base64の方がバイト数が少ないのに、なんでバイト数が増えるQuoted-Printableを使うの?)変換ルールは、ヨーロッパ系文字にあわせた仕様だったのね。
添付ファイル名について調べてみた限り、Outlook の 「送信メッセージで優先使用するエンコード方法」による違いはこうだった。
・日本語 (JIS) ⇒ 「B」エンコーディング
・日本語 (JIS 1 バイト カタカナ可) ⇒ 「B」エンコーディング
・日本語 (シフト JIS) ⇒ 「B」エンコーディング
・Unicode (UTF-8) ⇒ 変換ルール
日本語は「B」エンコーディング (Base64) の方が効率いいけど、多言語も扱うUnicode(UTF-8)は変換ルールが採用されるようだ。
【2026.3.4 その3】
BとQの境界線を調べたよ。Copilotの回答にあった「内部ロジック」の正体はこれだった。
■ Outlookの添付ファイル名変換ルール
B < 5N ≦ Q ※ Nは非ASCII文字数。
ちなみに UTF-8 だけかと思ったけど、Latin-1 もこのルールだったよ。結局、こういうことだった。
~ Geminiの回答 ~
『「UTF-8(マルチバイト)」でも「Latin-1(シングルバイト)」でも共通して 5N だったのは、結局のところ 「8ビット目のフラグが立っている文字(= 非ASCII文字)を、いかに効率よく7ビットの網(メールサーバー)に通すか」 という、1970〜80年代から続くメールの基本設計に由来していたわけです。』
文字エンコード方法とOSのロケールの両方を見て、BとQのどっちが効率いいか判断してもらえると、『さすがMS先輩、Apple小僧とは違うね』と称賛されると思う。
【2026.3.6】
iPhone標準メーラーは、添付ファイル名が RFC2047 の「B」エンコーディングには対応してるけど、「Q」エンコーディングには未対応。新しいほうのRFC2231は対応してた。
// 添付ファイルに関する処理 抜粋
$filename = "あ.xlsx";
// RFC2047 B は OK
$filename_encoded = mb_encode_mimeheader($filename, "UTF-8", "B");
$body = "Content-Type: application/octet-stream; name=\"{$filename_encoded}\"\r\n";
$body .= "Content-Disposition: attachment; filename=\"{$filename_encoded}\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
// RFC2047 Q は NG
$filename_encoded = mb_encode_mimeheader($filename, "UTF-8", "Q");
$body = "Content-Type: application/octet-stream; name=\"{$filename_encoded}\"\r\n";
$body .= "Content-Disposition: attachment; filename=\"{$filename_encoded}\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
// RFC2231 は OK
$filename_encoded = rawurlencode($filename);
$body = "Content-Type: application/octet-stream;\r\n";
$body .= "Content-Disposition: attachment; filename*=UTF-8''{$filename_encoded}\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
0 件のコメント:
コメントを投稿