![为什么需要 base64(又为什么我不能直接通过电子邮件发送二进制文件)?](https://linux22.com/image/1308555/%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%20base64%EF%BC%88%E5%8F%88%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E4%B8%8D%E8%83%BD%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6%E5%8F%91%E9%80%81%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%EF%BC%89%EF%BC%9F.png)
我正在阅读有关 Base64 编码的资料,并在 Wikipedia 上发现了这一点:
当需要对需要存储并通过专门处理文本数据的媒体传输的二进制数据进行编码时,通常使用 Base64 编码方案。
...给出的例子是通过电子邮件发送二进制文件。
我试图理解为什么需要 base64。由于二进制数据是一堆字节,难道它不能直接转换为 ASCII(即文本数据)吗?为什么需要 base64?或者电子邮件对 ASCII 中的控制字符存在问题?
答案1
有一个很好的维基百科文章关于这一点。
ARPAnet 使用的 NCP 最早的迭代更像是比特流而非字节流,或者尝试协商一个方便的字节大小;8 位字节直到后来才标准化。还有几次尝试创建可以在不同机器上运行的文件传输协议(邮件最初是 FTP 协议的一项功能,主要是作为MAIL
和MLFL
命令,然后拆分成中期计划, 之后邮件传输协议.)。这些机器通常具有不同的字符编码(ASCII 和 EBCDIC),甚至不同的字节大小,8 位字节 vs 6 位 vs ...
因此,邮件传输函数最初被定义为传输相对较短的纯文本消息;具体来说,就是“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 请求函数如下所述。换句话说,该软件没有8 位清洁。
数据传输
TCP 连接支持 8 位字节的传输,SMTP 数据为 7 位 ASCII 字符,每个字符以 8 位字节的形式传输,高位清零。
即使在 8 位 ISO-8859-# 字符编码普及之后,这种情况仍然持续了很长时间。尽管有些服务器已经是 8 位的,但许多其他服务器还没有,盲目发送 8 位数据会导致消息混乱。
之后,“扩展 SMTP”已发布,允许邮件服务器声明它们支持的 SMTP 扩展;其中之一是8BITMIME
,表示接收服务器可以安全地接受 8 位数据。MIME 消息部分可以有“内容传输编码:8bit”,表明它们没有以任何方式进行编码。
但是,SMTP 协议仍然基于行,并且具有 998 个八位字节的行限制,并且使用.
行 (0D 0A 2E 0D 0A) 作为“消息结束”指示符。这意味着,即使大多数二进制文件可以不加更改地发送,但包含此八位字节序列的文件仍有可能被解释为传输消息的结束,而文件的其余部分则被解释为 SMTP 命令,从而可能造成损坏。同样,接收服务器可能会截断长度超过 998 个八位字节的“行”。
2000 年,“BINARYMIME”ESMTP 扩展发表为RFC 3030,允许通过 SMTP 传输原始二进制数据。现在,消息以预先指定长度的块形式传输,使用零长度块作为终止符,不再需要 Base64 和类似编码。不幸的是,很少有 SMTP 服务器支持此扩展;例如,Postfix 和 Exim4 都没有CHUNKING
在回复 EHLO 时做广告。要利用 BINARYMIME,它必须得到全部消息路径中的服务器数量可以不止一两个。
也可以看看:
- RFC 765:文件传输协议
- RFC 772:邮件传输协议
- RFC 821:简单邮件传输协议
- 维基百科:8 位清洁
- 维基百科:8比特微信号
答案2
一些较旧的电子邮件系统和软件没有8 位清洁,第 8 位用作控制字符。这足以弄乱二进制文件,因此需要 Base64(或其他编码方案)。