MIME 电子邮件主题等 headers 与 utf8:首先拆分,然后编码?

MIME email Subject etc. headers vs. utf8: first split, then encode?

让我们来看看这个主题行,

$ echo -n 台電用戶意見電子信箱-信件受 | base64
5Y+w6Zu755So5oi25oSP6KaL6Zu75a2Q5L+h566xLeS/oeS7tuWPlw==

它(连同“主题:”等)在编码时超过 limits。所以, 一些邮寄者(某电力公司的)先编码,再拆分:

Subject: =?utf-8?B?5Y+w6Zu755So5oi25oSP6KaL6Zu75a2Q5L+h566xLeS/oeS7?=
 =?utf-8?B?tuWPl+eQhumAmuefpQ==?=

(但这可能很容易“破坏”UTF-8 多字节字符。)

其他邮件程序(例如 Gnus)首先拆分它,然后对其进行编码:

Subject: =?utf-8?B?5Y+w6Zu755So5oi25oSP6KaL6Zu75a2Q5L+h566xLeS/oeS7tg==?=
 =?utf-8?B?5Y+X55CG6YCa55+l?=

后者保证在所有邮件阅读器中正确呈现 今天。

我的问题是,某些邮件阅读器(例如 Gmail android app) 被前者噎住了?

邮件读者应该总是先将两个字符串粘贴在一起,然后 解码? (所以 Gmail 应用程序是错误的。)

或者是不是也可以先解码,然后把解码后的两个字符串粘贴在一起。 (所以邮件软件有问题?)

(我认为 Quoted Printable 也会出现同样的问题,而不仅仅是 Base64。)

确实,如果你仔细想想,说=?utf-8?B?...?=意味着...东西应该是一个有效的UTF-8字符串,(就其本身而言,) 正确的?所以邮寄软件有问题!

同样,可能从未定义过如何将 =?utf-8?B?...?= 分成两个短语的语法,因为这应该事先处理好,因为创建 =?utf-8?B?...?= 字符串应该始终是最后一步。

因此:邮寄软件:GUILTY。 Gmail:无罪。

你所拥有的是 RFC 2047 中定义的 encoded word 语法。您可以混合未编码的标记和各种编码,以便每个编码的词本身都应该有效。先解码,再组合看起来是正确的做法。

阅读 RFC,一些注释和示例与您的案例相关。

当然,RFC 介绍中的注释“虽然不幸...”告诉您整个区域总是一团糟。

根据 RFC 2047 § 8 的示例(和整体解释),编码字不会神奇地跨越多个实例:

  • =?UTF-8?Q?a?= 既不能继续前一个编码字,也不能继续下一个编码字 - 它是,它是什么:a.
  • 当我们混合文本编码时更明显:=?UTF-8?Q?a?= =?ISO-8859-1?Q?b?= 应该呈现为 ab,很明显,当下一个编码字是又是 UTF-8(不同的文本编码肯定使用不同的字节)。

作为合乎逻辑的结果,UTF-8 应该按字符而不是字节拆分。这意味着:不应剪切编码 B (Base64) 和 Q (Quoted)(除非剪切恰好也在编码文本的字符之间)——剪切必须发生在之前。

我只能猜测这对一些程序员来说“太复杂了”,他们只是认为“无论如何它不会破坏任何东西——到目前为止没有人抱怨”。但是,如果必须切割编码字,正确的方法是首先对其进行解码,以便可以按字符(而不是按字节)切割文本,然后再次对两个部分进行编码。一个警告是:谁这样做也必须支持所述文本编码 - 虽然 UTF-8 今天很普遍,但软件是否也知道在哪里剪切 Shift-JIS and Big5 and UTF-16BE