为什么需要 base64(也就是为什么我不能通过电子邮件发送二进制文件)?

Coo*_*ter 34 email base64

我正在阅读 Base64 编码,并在维基百科上找到了这个:

当需要对二进制数据进行编码时,通常会使用 Base64 编码方案,这些数据需要通过旨在处理文本数据的媒体进行存储和传输。

...给出的示例是通过电子邮件发送二进制文件。

我试图理解为什么需要 base64。既然二进制数据是一堆字节,那岂不是可以直接转成ASCII,也就是文本数据?为什么根本需要base64?或者电子邮件的 ASCII 控制字符是否有问题?

use*_*686 40

有一个很好的维基百科文章


ARPAnet 使用的最早的 NCP 迭代更像是位流而不是字节流,或者尝试协商方便的字节大小;8 位字节只是在很久以后才标准化。还有一些尝试创建可以在不同机器上工作的文件传输协议(邮件最初是 FTP 协议的一个功能,主要作为MAILMLFL命令,然后拆分为MTP,后来拆分为SMTP。)。这些机器通常具有不同的字符编码 - ASCII 与 EBCDIC - 甚至不同的字节大小,8 位字节与 6 位与 ...

因此,邮件传输功能最初是为传输相对较短的纯文本消息而定义的;具体来说,“NVT-ASCII”。例如,RFC 772说:

邮件代理和存储

邮件从发送主机中的存储设备传输到接收主机中的存储设备。由于两个系统中的数据存储表示不同,因此可能需要对邮件执行某些转换。例如,NVT-ASCII 在不同的系统中有不同的数据存储表示。PDP-10 通常将 NVT-ASCII 存储为五个 7 位 ASCII 字符,在 36 位字中左对齐。360 将 NVT-ASCII 存储为 32 位字中的四个 8 位 EBCDIC 代码。Multics 将 NVT-ASCII 存储为 36 位字中的四个 9 位字符。

为简单起见,所有数据都必须在 MTP 中表示为 NVT-ASCII。这意味着在传输文本时,无论发送主机和接收主机是否不同,字符都必须转换为标准的 NVT-ASCII 表示。发送方将数据从其内部字符表示转换为标准的 8 位 NVT-ASCII 表示(请参阅 TELNET 规范)。接收方将数据从标准形式转换为自己的内部形式。根据该标准,应该使用序列来表示一行文本的结尾。

即使通过线路传输 8 位,第 8 位也经常会被丢弃或损坏,因为不需要保留它;事实上,一些协议要求将第 8 位设置为零,例如下面引用的初始SMTP RFC。换句话说,该软件不是8-bit clean

数据传输

TCP 连接支持 8 位字节的传输。SMTP 数据是 7 位 ASCII 字符。每个字符作为一个 8 位字节传输,高位清零。

即使在 8 位 ISO-8859-# 字符编码变得普遍之后,这种情况仍然存在很长时间。尽管有些服务器已经是 8 位清洁的,但许多其他服务器不是,盲目发送 8 位数据会导致消息被破坏。

后来,“Extended SMTP”发布,允许邮件服务器声明它们支持的 SMTP 扩展;其中之一是8BITMIME,表示接收服务器可以安全地接受 8 位数据。MIME 消息部分可以有“ Content-Transfer-Encoding : 8bit”,表明它们没有以任何方式编码。

但是,SMTP 协议仍然是基于行的,并且具有 998 个八位字节的行限制,并且使用.一行 (0D 0A 2E 0D 0A) 作为“消息结束”指示符。这意味着即使大多数二进制文件可以原封不动地发送,包含此八位字节序列的文件仍有可能被解释为传输消息的结尾,而文件的其余部分则被解释为 SMTP 命令,这可能会造成损坏。类似地,接收服务器可能会切断超过 998 个八位字节的“行”。

2000 年,“BINARYMIME”ESMTP 扩展作为RFC 3030发布,允许通过 SMTP 传输原始二进制数据。消息现在以预先指定长度的块传输,零长度块用作终止符,不再需要 Base64 和类似的编码。不幸的是,很少有 SMTP 服务器支持这个扩展;例如,Postfix 和 Exim4 都没有CHUNKING在回复 EHLO 时做广告。要利用 BINARYMIME,消息路径中的所有服务器都必须支持它,这可能不仅仅是一两个。

也可以看看:


Ren*_*nan 8

一些较旧的电子邮件系统和软件不是8 位干净的,第 8 位用作控制字符。这足以弄乱二进制文件,因此需要 Base64(或其他编码方案)。