维基百科上说
当需要对二进制数据进行编码时,通常使用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
以传输相同数量信息的更多数据为代价,确保接收者能够以预期的方式解码数据,即使接收者对其余字符集有不同的解释。
为什么不看看当前定义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最初被设计为一种允许二进制数据附加到电子邮件的方式,作为多用途互联网邮件扩展的一部分。
而不是转义特殊字符
我将给您一个非常不同但真实的例子:我编写javascript代码以在浏览器中运行。HTML标记有ID值,但是在ID中哪些字符有效是有限制的。
但是我希望我的ID无损地引用文件系统中的文件。现实中的文件中可以有各种各样奇怪而奇妙的字符,从感叹号、重音字符、波浪号,甚至是表情符号!我不能这样做:
<div id="/path/to/my_strangely_named_file!@().jpg">
<img src="http://myserver.com/path/to/my_strangely_named_file!@().jpg">
Here's a pic I took in Moscow.
</div>
假设我想运行这样的代码:
# ERROR
document.getElementById("/path/to/my_strangely_named_file!@().jpg");
我认为这段代码在执行时会失败。
使用Base64,我可以引用一些复杂的东西,而不用担心哪种语言允许哪些特殊字符以及哪些需要转义:
document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");
与使用MD5或其他哈希函数不同,您可以反向编码以找出真正有用的数据。
我希望我64年前就知道Base64。如果使用' encodeURIComponent '和str.replace(' \n ', ' \\n '),我就不会把我的头发扯掉了。
SSH传输文本:
如果你试图通过ssh传递复杂的数据(例如,一个dotfile,这样你就可以得到你的shell个性化),在没有base64的情况下,祝你好运。这是你用64进制来做的(我知道你可以使用SCP,但这需要多个命令-这使得ssh到服务器的键绑定复杂化):
https://superuser.com/a/1376076/114723
“媒体是”是什么意思
设计用于处理文本数据”?
这些协议被设计用来处理文本(通常只有英文文本),而不是二进制数据(如.png和.jpg图像)。
他们可以处理二进制=>他们可以
处理任何事情。
但反过来就不对了。为表示文本而设计的协议可能不恰当地处理恰好包含以下内容的二进制数据:
字节0x0A和0x0D,用于行结束,因平台而异。
其他控制字符,如0x00 (NULL = C字符串结束符),0x03(文本结束),0x04(传输结束),或0x1A (DOS文件结束),可能过早地表示数据结束。
大于0x7F的字节(如果协议是为ASCII设计的)。
无效的UTF-8字节序列。
所以你不能仅仅通过基于文本的协议发送二进制数据。您只能使用表示非空格非控制ASCII字符的字节,其中有94个。选择64进制的原因是,它可以更快地计算2的幂,而64是最大的。
但有一个问题。这是怎么回事
系统仍然没有达成共识
像这样的编码技术很常见
utf - 8 ?
至少在网络上,他们大多是这样做的。大多数站点使用UTF-8。
在西方的问题是,有很多旧的软件,1字节= 1个字符,不能与UTF-8工作。
东方的问题在于他们对GB2312和Shift_JIS等编码的依赖。
事实上,微软似乎仍然没有从选择错误的UTF编码中恢复过来。如果您想使用Windows API或Microsoft C运行时库,则只能使用UTF-16或区域设置的“ANSI”编码。这使得使用UTF-8非常痛苦,因为您必须一直进行转换。
更重要的是,媒体验证字符串编码,因此我们希望确保处理应用程序可以接受数据(例如,不包含表示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可能认为重要的数据。