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

问题描述

让我们以这个主题行,@H_502_1@

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

它(连同“主题:”等)在编码时超过了 limits。所以, 一些邮件程序(某个电力公司的)首先对其进行编码,然后将其拆分:@H_502_1@

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

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

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

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

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

我的问题是,某些邮件阅读器(例如 Gmail android 应用程序)对前者感到窒息?@H_502_1@

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

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

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

Broken UTF-8

@H_502_1@

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

同样,可能从来没有定义过如何将 =?utf-8?B?...?= 拆分为两个短语的语法,因为应该事先注意,因为创建 =?utf-8?B?...?= 字符串应该始终是最后的步骤。@H_502_1@

所以:邮件软件:有罪。 Gmail:无罪。@H_502_1@

解决方法

根据 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-JISBig5UTF-16BE?>

,

您拥有的是 RFC 2047 中定义的 encoded word 语法。您可以混合未编码的标记和各种编码,因此每个编码的单词本身都应该是有效的。首先解码,然后组合看起来是正确的方法。

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

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