内容传输编码7位或8位

123
在发送电子邮件内容时,需要设置“Content Transfer Encoding”头部。我注意到我收到的许多电子邮件头部都使用“7bit”,而有些则使用“8bit”。
这两者之间有什么区别?哪一个是推荐的?在电子邮件正文中是否需要特殊编码以设置这些头部?

我认为没有必要设置这个头部,是吗?我开始处理电子邮件,我看到过没有这个头部的电子邮件 - 非常简单,非多部分,仅ASCII文本消息。 - osullic
2个回答

366

这段内容可能有些晦涩难懂,但是RFC 1341的“Content-Transfer-Encoding”部分包含了所有细节:

http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html

The situation is getting worse. Here's my summary:
Background
SMTP, as defined in RFC 821, restricts mail to lines of 1000 characters of 7 bits each. This means that none of the bytes sent down the pipe can have the most significant ("highest-order") bit set to "1". However, the content we want to send often does not obey this restriction inherently, such as image files or text files containing Unicode characters. Therefore, "transfer encoding" needs to be used to describe how to work around the mismatch. The values for the Content-Transfer-Encoding header describe the rule chosen to solve this problem.
7Bit Encoding
"7bit" simply means "My data consists only of US-ASCII characters, which only use the lower 7 bits for each character." This guarantees that all bytes in the content already adhere to SMTP restrictions and require no special treatment. It can be read as-is.

请注意,当您选择7bit时,您同意您内容中的所有行的长度都不超过1000个字符。

只要您的内容遵循这些规则,7bit就是最好的传输编码,因为没有额外的工作需要处理;您只需按照字节的顺序读写即可。同时,7bit内容易于理解。这里的想法是,如果您只是写“纯英语文本”,那么就没问题了。但是这在2005年不是真的,今天也不是。

8位编码

8bit表示“我的数据可能包括扩展ASCII字符;它们可能使用第8(最高)位来指示标准US-ASCII 7位字符以外的特殊字符。”与7bit一样,仍然有1000个字符的行限制。

"8位"和"7位"一样,在数据写入或从网上读取时不会转换任何字节。只是表示您不能保证没有任何一个字节的最高位设置为"1"。
这似乎比"7位"更有用,因为它使您在内容方面更加自由。然而,RFC 1341包含了这个小提示:

截至本文件发布时,在标准化的Internet传输协议中,无法在邮件正文中包含未编码的8位或二进制数据。因此,在Internet上实际上不存在适用于"8bit"或"binary"内容传输编码的情况。

RFC 1341出版已有20多年。此后我们得到了RFC 6152中的8位MIME扩展名。但即使如此,仍可能适用行限制。
请注意,此扩展程序并未消除 SMTP 服务器限制行长度的可能性;服务器可以实施此扩展程序,但仍然设置不低于 1000 个八位字节的行长度限制。

二进制编码

binary8bit 相同,只是没有行长度限制。您仍然可以包含任何字符,并且没有额外的编码。类似于 8bit,RFC 1341 指出它并不是一个真正合法的编码传输编码。RFC 3030 使用 BINARYMIME 扩展了此功能。

可引用打印

在出现 8BITMIME 扩展程序之前,需要一种方法来通过 SMTP 发送无法使用 7bit 的内容。HTML 文件(可能具有超过 1000 个字符的行)和带有国际字符的文件是很好的例子。设计了 quoted-printable 编码(在 RFC 1341 的第 5.1 节中定义)来处理此问题。它做了两件事:
  • 定义如何转义非美国ASCII字符,以便它们可以用仅7位字符表示。(简短版本:它们将显示为等号加上两个7位字符。)
  • 定义行不超过76个字符,并且换行符将使用特殊字符表示(然后进行转义)。

引用可打印格式由于转义和短行比7bit8bit更难被人类阅读,但它支持更广泛的可能内容。

Base64编码

如果您的数据主要是非文本(例如:图像文件),您没有太多选择。7bit不适用。8bitbinary在MIME扩展RFC之前不受支持。quoted-printable可以工作,但效率非常低下(每个字节将由3个字符表示)。

base64是这种类型数据的一个好的解决方案。它将3个原始字节编码为4个US-ASCII字符,相对高效。RFC 1341进一步限制了base64编码数据的行长度为76个字符以适应SMTP消息,但当您只是在固定长度处拆分或连接任意字符时,这相对容易管理。最大的缺点是base64编码数据几乎完全无法被人类阅读,即使在其底层只是“纯文本”。

14
这个回答很棒,我希望我可以点赞100次!不过有一个问题:这些规则适用于附件吗?例如,我有一个附加在电子邮件中的XML文件,其中XML文件的内容包含UTF-8数据。这里应该采取什么正确的方法呢? - TrojanName
2
@TrojanName:是的,这些适用于所有电子邮件内容,包括附件。(在内部,一切都只是 MIME 的“部分”,但那是另一回事。)你仍然需要以某种方式编码你的内容才能将其放入电子邮件中。 - Craig Walker
2
@TrojanName:任何文件都是“二进制”文件,无论它是否也可以被视为文本,因此BINARYMIME和BINARY可用(尽管它们对于任何内容都可用)。7Bit不好,因为您的UTF-8内容需要8位来表示内容。8Bit也不好,因为它需要行长度限制,而这些限制不是您内容的一部分。 - Craig Walker
3
这意味着只剩下Quoted Printable或Base64可用,两者都可以成功地将XML文档编码到电子邮件中。注意,这两种编码方式都会使原始格式更难以阅读(Base64是不可读的,QP也很困难)。但人类可读性是次要问题;只要您始终假设必须对其进行解码和编码,那么就没问题了。 - Craig Walker
2
附加限制:8位不应包括空值或非结束行CR或LF。 - Max
显示剩余4条评论

1

使用content-transfer-encoding: 7bit,在正文中使用的字节(或更准确地说,在部件的边界内)应该表示ASCII字符,而不是扩展ASCII字符。这意味着0-127十进制(第8位未使用)。

由于第8位未使用,这意味着您不能使用utf-8iso8859-7字节来编码文本,因为它们使用第8位。也不能添加二进制内容。

使用content-transfer-encoding: 8bit,您可以使用任何可能的字节,这意味着您可以使用utf-8字节或iso8859-7字节来编码文本(都假定在SMTP中使用了8BITMIME扩展)。但是,由于仍然适用于最大行限制,仍然不安全添加二进制内容,这可能会使您的字节断开并带有换行符。

即使使用7bit content-transfer-encoding,只要您仍将字节保持在0-127的边界之间,仍然可以将content-typecharset参数设置为utf-8

7bit内容传输编码来表示ASCII之外的字符的一种可能方式是使用HTML代码字符(带content-type:text / html)。

许多电子邮件客户端将根据情况将content-transfer-encoding设置为7bit8bit。例如,发送英文文本时使用7bit,发送多语言文本时使用8bit。还有quoted-printablebase64的选项,它们的字符也不使用第8位,但这超出了问题的范围。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接