为什么使用Base64"only"来编码二进制数据?

Why Base64 is used "only" to encode binary data?

我在当今的互联网上看到了很多关于 base64 用法的资源。据我了解,所有这些资源似乎都以不同的方式拼写出单个用例:在 Base64 中编码 binary 数据以避免在 [=13] 期间将其 misinterpreted/corrupted 作为其他内容=]transit(通过中间系统)。但我没有发现任何可以解释以下内容的内容:

  1. 为什么二进制数据会被中间系统破坏?如果我将图像从服务器发送到客户端,任何中间 servers/systems/routers 将简单地将数据转发到客户端路径中的下一个适当的 servers/systems/routers。为什么中间 servers/systems/routers 需要 解释 它收到的东西?在当今的 Internet 中,可以 corrupt/wrongly 解释它接收到的数据的此类系统的任何示例?
  2. 为什么我们只担心 二进制 数据被破坏。我们使用 Base64 是因为我们确信那 64 个字符永远不可能是 corrupted/misinterpreted。但是按照同样的逻辑,任何不属于base64字符的文本字符都可以是corrupted/misinterpreted。那么,为什么 base64 仅用于编码 binary 数据?延伸同样的思路,当我们使用浏览器时,javascript和HTML文件是以base64形式传输的吗?

使用 Base64 有两个原因:

  1. 不是 8 位干净的系统。这源于“以前”一些系统认真对待 ASCII,并且只考虑(并传输)任何 8 位字节中的 7 位(因为 ASCII 仅使用 7 位,只要所有内容实际上是ASCII).
  2. 8 位干净的系统,但尝试使用特定编码解码数据(即他们假设它是 well-formed 文本)。

当通过它传输二进制(即non-text)数据时,这两种方法都会产生类似的效果:它们会尝试将二进制数据解释为字符编码中的文本数据,这显然没有意义(因为 二进制数据中没有字符编码),因此以 un-fixable 方式修改数据。

Base64 以一种相当巧妙的方式解决了这两个问题:它将所有可能的二进制数据流映射到有效的 ASCII 文本中:第 8 位永远不会设置在 Base64 编码数据上,因为只使用常规的旧 ASCII 字符。

这几乎也解决了第二个问题,因为最常用的字符编码(UTF-16 和 UCS-2 除外,其中少数 lesser-used 是显着的例外)是 ASCII 兼容的,这意思是:所有有效的 ASCII 流恰好也是大多数常见编码中的有效流,并且表示相同的字符(这些编码的示例是 ISO-8859-* 系列、UTF-8 和大多数 Windows 代码页)。

关于你的第二个问题,答案是two-fold:

  1. 文本数据通常带有某种 meta-data(数据中的 HTTP header 或 meta-tag)描述用于解释它的编码。为处理此类数据而构建的系统理解并容忍或解释这些标签。
  2. 一些情况下(特别是邮件传输)我们确实必须使用各种编码技术来确保文本不会被破坏.这可能是使用 quoted-printable 编码,有时甚至是在 Base64 中包装文本数据。

最后但同样重要的是:Base64 有一个严重的缺点,那就是效率低下。对于每 3 个字节的数据进行编码,它会产生 4 个字节的输出,从而使数据大小增加约 33%。这就是为什么在不必要的时候应该避免它。

BASE64 的用途之一是发送电子邮件。

邮件服务器使用终端来传输数据。翻译也很常见,例如\c\r成单\n,反之。注意:也不能保证可以使用 8 位(电子邮件标准是旧的,它也允许非“互联网”电子邮件,因此使用 ! 而不是 @)。此外,系统可能不完全是 ASCII。

同时 \n\n. 被认为是正文的结尾,mboxes 也使用 \n>From 来标记新邮件的开始,所以当 8 位标志在邮件服务器中很常见时,问题是没有完全解决。

BASE64 是解决所有问题的好方法:内容只是作为所有服务器都必须知道的字符发送,encoding/decoding 的问题只需要发送方和接收方协议(以及正确的程序),无需担心中间的许多中继服务器。注意:所有 \c\r\n 等都将被忽略。

注意:您也可以使用 BASE64 对 URL 中的字符串进行编码,而无需担心网络浏览器的解释。您可能还会在配置文件中看到 BASE64(例如包含图标):特殊制作的图像可能不会被解释为配置。 Just BASE64 可以很方便地将二进制数据编码成不是为二进制数据设计的协议。