维基百科上说
当需要对二进制数据进行编码时,通常使用Base64编码方案,这些数据需要通过设计用于处理文本数据的媒体存储和传输。这是为了确保数据在传输过程中保持完整而不被修改。
但是,数据不总是以二进制存储/传输吗?因为我们机器的内存存储二进制,这只是取决于你如何解释它?因此,无论您将位模式010011010110000101101110编码为ASCII中的Man还是Base64中的TWFu,最终都将存储相同的位模式。
如果最终的编码是用0和1表示的,并且每台机器和媒体都可以处理它们,那么数据是用ASCII还是Base64表示有什么关系呢?
“设计用于处理文本数据的媒体”是什么意思?他们可以处理二进制=>他们可以处理任何东西。
谢谢大家,我想我现在明白了。
当我们发送数据时,我们不能确定数据将以与我们预期的相同格式进行解释。因此,我们发送以双方都能理解的某种格式(如Base64)编码的数据。这样,即使发送方和接收方对相同内容的解释不同,但由于他们对编码格式达成一致,数据也不会被错误地解释。
来自Mark Byers的例子
如果我想发送
Hello
world!
一种方法是用ASCII码发送
72 101 108 108 111 10 119 111 114 108 100 33
但是字节10在另一端可能不能被正确地解释为换行符。因此,我们使用ASCII的一个子集来像这样编码
83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61
以传输相同数量信息的更多数据为代价,确保接收者能够以预期的方式解码数据,即使接收者对其余字符集有不同的解释。
用XML编码二进制数据
假设您想在XML文档中嵌入一对图像。图像是二进制数据,而XML文档是文本。但是XML不能处理嵌入的二进制数据。那么该怎么做呢?
一种选择是用base64编码图像,将二进制数据转换为XML可以处理的文本。
而不是:
<images>
<image name="Sally">{binary gibberish that breaks XML parsers}</image>
<image name="Bobby">{binary gibberish that breaks XML parsers}</image>
</images>
你该怎么做:
<images>
<image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
<image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
</images>
XML解析器将能够正确地解析XML文档并提取图像数据。
为什么不看看当前定义Base64的RFC呢?
Base encoding of data is used in
many situations to store or transfer
data in environments that, perhaps for
legacy reasons, are restricted to
US-ASCII [1] data.Base encoding can
also be used in new applications
that do not have legacy restrictions,
simply because it makes it possible
to manipulate objects with text
editors.
In the past, different applications
have had different requirements and
thus sometimes implemented base
encodings in slightly different
ways. Today, protocol specifications
sometimes use base encodings in
general, and "base64" in particular,
without a precise description or
reference. Multipurpose Internet Mail
Extensions (MIME) [4] is often used
as a reference for base64 without
considering the consequences for
line-wrapping or non-alphabet
characters. The purpose of this
specification is to establish common
alphabet and encoding
considerations. This will hopefully
reduce ambiguity in other
documents, leading to better
interoperability.
Base64最初被设计为一种允许二进制数据附加到电子邮件的方式,作为多用途互联网邮件扩展的一部分。
更重要的是,媒体验证字符串编码,因此我们希望确保处理应用程序可以接受数据(例如,不包含表示EOL的二进制序列)。
假设您希望在编码为UTF-8的电子邮件中发送二进制数据——如果1和0的流创建的序列不是有效的UTF-8编码的Unicode,则电子邮件可能无法正确显示。
当我们想在URL中编码对URL本身无效的字符时,同样的事情也会发生在URL中:
http://www.foo.com/hello我的朋友-> http://www.foo.com/hello%20my%20friend
这是因为我们想在一个系统上发送一个空间,这个系统会认为这个空间很臭。
我们所做的只是确保在已知的良好、可接受且无害的比特序列与另一个比特文字序列之间存在1对1的映射,并且处理应用程序不会区分编码。
在你的例子中,man可能是第一种形式的有效ASCII;但通常你可能想要传输随机二进制值(例如在电子邮件中发送图像):
MIME-Version: 1.0
内容描述:"Base64编码的。gif"
内容类型:/ gif图像;name = " a.gif "
Content-Transfer-Encoding: Base64
附加:附件;文件名= " a.gif "
在这里,我们看到GIF图像以base64编码为电子邮件的一个块。电子邮件客户端读取标题并解码。由于编码,我们可以确保GIF不包含任何可能被解释为协议的内容,并且我们避免插入SMTP或POP可能认为重要的数据。
您的第一个错误是认为ASCII编码和Base64编码是可互换的。事实并非如此。它们有不同的用途。
当您用ASCII编码文本时,您从文本字符串开始,并将其转换为字节序列。
在Base64中编码数据时,从一个字节序列开始,并将其转换为文本字符串。
为了理解为什么Base64首先是必要的,我们需要一点计算的历史。
计算机以二进制(0和1)进行通信,但人们通常希望使用更丰富的表单数据(如文本或图像)进行通信。为了在计算机之间传输这些数据,首先必须将其编码为0和1,然后发送,然后再次解码。以文本为例,有许多不同的方法来执行这种编码。如果我们都能同意一种编码,那就简单多了,但遗憾的是,事实并非如此。
Originally a lot of different encodings were created (e.g. Baudot code) which used a different number of bits per character until eventually ASCII became a standard with 7 bits per character. However most computers store binary data in bytes consisting of 8 bits each so ASCII is unsuitable for tranferring this type of data. Some systems would even wipe the most significant bit. Furthermore the difference in line ending encodings across systems mean that the ASCII character 10 and 13 were also sometimes modified.
为了解决这些问题,引入了Base64编码。这允许您将任意字节编码为已知可以安全发送而不会被损坏的字节(ASCII字母数字字符和一对符号)。缺点是使用Base64编码消息会增加它的长度——每3个字节的数据被编码为4个ASCII字符。
为了可靠地发送文本,您可以首先使用您选择的文本编码(例如UTF-8)将其编码为字节,然后使用Base64将结果二进制数据编码为可以安全地以ASCII编码发送的文本字符串。接收方将不得不反转此过程以恢复原始消息。当然,这需要接收方知道使用了哪些编码,而这些信息通常需要单独发送。
历史上,它被用于编码电子邮件消息中的二进制数据,其中电子邮件服务器可能修改行结束符。一个更现代的例子是使用Base64编码直接在HTML源代码中嵌入图像数据。这里需要对数据进行编码,以避免'<'和'>'这样的字符被解释为标记。
下面是一个工作示例:
我想发一条短信,两行字:
Hello
world!
如果我把它作为ASCII(或UTF-8)发送,它会像这样:
72 101 108 108 111 10 119 111 114 108 100 33
字节10在某些系统中被损坏,因此我们可以将这些字节以Base64编码为Base64字符串:
SGVsbG8Kd29ybGQh
当使用ASCII编码时,看起来是这样的:
83 71 86 115 98 71 56 75 100 50 57 121 98 71 81 104
这里的所有字节都是已知的安全字节,因此任何系统破坏此消息的可能性很小。我可以发送这个而不是我的原始消息,并让接收者反向处理以恢复原始消息。