问题描述
让我们以这个主题行,
$ 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 应用程序)对前者感到窒息?
邮件读者是否应该始终先将两个字符串粘贴在一起,然后 解码? (所以 Gmail 应用是错误的。)
或者也可以先解码,然后将两个解码后的字符串粘贴在一起。 (所以邮件软件有问题?)
(我认为 Quoted Printable 也会出现同样的问题,不仅仅是 Base64。)
确实,如果你仔细想想,说 =?utf-8?B?...?=
意味着 ...
的东西应该是一个有效的 UTF-8 字符串,(就其本身而言)对吗?所以邮件软件是错误的!
同样,可能从来没有定义过如何将 =?utf-8?B?...?=
拆分为两个短语的语法,因为应该事先注意,因为创建 =?utf-8?B?...?=
字符串应该始终是最后的步骤。
所以:邮件软件:有罪。 Gmail:无罪。
解决方法
根据 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 和 Big5 和 UTF-16BE?>
,您拥有的是 RFC 2047 中定义的 encoded word
语法。您可以混合未编码的标记和各种编码,因此每个编码的单词本身都应该是有效的。首先解码,然后组合看起来是正确的方法。
阅读 RFC,其中一些注释和示例与您的案例相关。
当然,RFC 介绍中的注释“虽然很不幸……”告诉您整个区域总是一团糟。