Laz*_*zer 246 algorithm binary base64 ascii character-encoding
维基百科说
当需要编码需要通过设计用于处理文本数据的媒体存储和传输的二进制数据时,通常使用Base64编码方案.这是为了确保数据在运输过程中保持完好无需修改.
但是,数据是否总是以二进制形式存储/传输,因为我们的机器存储二进制文件的内存只取决于你如何解释它?因此,无论您编码位模式010011010110000101101110
为Man
ASCII或如TWFu
为Base64,你最终将存储相同的位模式.
如果最终编码是零和1,并且每台机器和媒体都可以处理它们,那么如果数据表示为ASCII或Base64,这又如何重要?
什么是"旨在处理文本数据的媒体"?他们可以处理二元=>他们可以处理任何事情.
谢谢大家,我想我现在明白了.
当我们发送数据时,我们无法确定数据的解释格式是否与我们预期的相同.因此,我们发送以双方都理解的某种格式(如Base64)编码的数据.这样,即使发送方和接收方以不同方式解释相同的内容,但由于它们对编码格式达成一致,因此数据不会被错误地解释.
如果我想发送
Hello
world!
Run Code Online (Sandbox Code Playgroud)
一种方法是用ASCII发送它
72 101 108 108 111 10 119 111 114 108 100 33
Run Code Online (Sandbox Code Playgroud)
但是字节10可能无法正确解释为另一端的换行符.因此,我们使用ASCII的子集对此进行编码
83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61
Run Code Online (Sandbox Code Playgroud)
以相同数量的信息传输的更多数据为代价,确保接收器能够以预期的方式解码数据,即使接收器恰好对字符集的其余部分有不同的解释.
Mar*_*ers 261
你的第一个错误是认为ASCII编码和Base64编码是可以互换的.他们不是.它们用于不同的目的.
要理解为什么Base64首先是必要的,我们需要一点点计算历史.
计算机以二进制 - 0和1进行通信 - 但人们通常希望与更丰富的表单数据(如文本或图像)进行通信.为了在计算机之间传输这些数据,首先必须将其编码为0和1,然后再发送,然后再解码.以文本为例 - 有许多不同的方法来执行此编码.如果我们都能就单一编码达成一致就会简单得多,但遗憾的是情况并非如此.
最初创建了许多不同的编码(例如Baudot代码),每个字符使用不同的位数,直到最终ASCII成为每个字符7位的标准.但是,大多数计算机以字节为单位存储二进制数据,每个字节由8位组成,因此ASCII不适合传输此类数据.有些系统甚至会擦掉最重要的位.此外,跨系统的行结束编码的差异意味着ASCII字符10和13有时也被修改.
为了解决这些问题,引入了Base64编码.这允许您将aribtrary字节编码为已知可安全发送而不会损坏的字节(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
Run Code Online (Sandbox Code Playgroud)
字节10在某些系统中已损坏,因此我们可以将这些字节作为Base64字符串进行64位编码:
SGVsbG8sCndvcmxkIQ==
使用ASCII编码时,如下所示:
83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61
Run Code Online (Sandbox Code Playgroud)
这里的所有字节都是已知的安全字节,因此任何系统都很可能会破坏此消息.我可以发送此消息而不是原始消息,让接收方反转该过程以恢复原始消息.
yfe*_*lum 57
假设您要在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>
Run Code Online (Sandbox Code Playgroud)
你做:
<images>
<image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
<image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
</images>
Run Code Online (Sandbox Code Playgroud)
XML解析器将能够正确解析XML文档并提取图像数据.
Bil*_*eal 37
为什么不查看当前定义Base64的RFC?
在许多情况下,数据的基本编码用于在环境中存储或传输
数据,这些环境可能由于遗留原因而限制为US-ASCII [1]数据.Base编码也可用于没有传统限制的新应用程序,只是因为它可以用文本编辑器操作对象.过去,不同的应用程序有不同的要求,因此有时以稍微不同的方式实现基本编码.今天,协议规范有时一般使用基本编码,特别是"base64",没有精确的描述或参考.多用途Internet邮件扩展(MIME)[4]通常用作base64的参考,而不考虑换行或非字母字符的后果.本规范的目的是建立常见的字母和编码注意事项.这有望减少其他文档中的歧义,从而实现更好的互操作性.
Base64最初被设计为允许二进制数据作为多用途Internet邮件扩展的一部分附加到电子邮件的方法.
Gil*_*oot 28
以下是我阅读其他人的帖子后的理解总结:
\n重要的!
\nBase64 编码并不意味着提供安全性
\nBase64 编码并不意味着压缩数据
\n为什么我们使用 Base64
\nBase64 是数据的文本表示形式,仅包含 64 个字符,即字母数字字符(小写和大写)、+、/ 和 =。\n这 64 个字符被视为 \xe2\x80\x98safe\xe2\x80\x99,即也就是说,与 <、> \\n 等许多其他字符不同,它们不会被旧计算机和程序误解。
\nBase64什么时候有用
\n我发现 base64 在将文件作为文本传输时非常有用。您获取文件的字节并将它们编码为 Base64,传输 Base64 字符串,然后从接收端执行相反的操作。
\n这与在发送电子邮件期间通过 SMTP 发送附件时使用的过程相同。
\n如何进行base64编码/解码
\n从 Base64 文本到字节的转换称为解码。\n从字节到 Base64 文本的转换称为编码。这与其他编码/解码的命名方式有点不同。
\nDotnet 和 Powershell
\nMicrosoft 的 Dotnet 框架支持将字节编码和解码为 Base64。Convert
在库中查找名称空间mscorlib
。
以下是您可以使用的 powershell 命令:
\n// Base64 encode PowerShell \n// See: https://adsecurity.org/?p=478\n$Text=\'This is my nice cool text\'\n$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)\n$EncodedText = [Convert]::ToBase64String($Bytes)\n$EncodedText\n\n\n// Convert from base64 to plain text \n[System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String(\'VABoAGkAcwAgAGkAcwAgAG0AeQAgAG4AaQBjAGUAIABjAG8AbwBsACAAdABlAHgAdAA=\'))\nOutput>This is my nice cool text \n
Run Code Online (Sandbox Code Playgroud)\nBash 有一个用于 Base64 编码/解码的内置命令。你可以这样使用它:
\n编码为 Base64:
\necho \'hello\' | base64\n\n
Run Code Online (Sandbox Code Playgroud)\n要将 Base64 编码文本解码为普通文本:
\necho \'aGVsbG8K\' | base64 -d\n\n
Run Code Online (Sandbox Code Playgroud)\nNode.js 还支持 base64。这是一个您可以使用的类:
\n\n/**\n * Attachment class.\n * Converts base64 string to file and file to base64 string\n * Converting a Buffer to a string is known as decoding.\n * Converting a string to a Buffer is known as encoding.\n * See: https://nodejs.org/api/buffer.html\n * \n * For binary to text, the naming convention is reversed.\n * Converting Buffer to string is encoding.\n * Converting string to Buffer is decoding.\n * \n */\nclass Attachment {\n constructor(){\n\n }\n\n /**\n * \n * @param {string} base64Str \n * @returns {Buffer} file buffer\n */\n static base64ToBuffer(base64Str) {\n const fileBuffer = Buffer.from(base64Str, \'base64\');\n // console.log(fileBuffer)\n return fileBuffer;\n }\n\n /**\n * \n * @param {Buffer} fileBuffer \n * @returns { string } base64 encoded content\n */\n static bufferToBase64(fileBuffer) {\n const base64Encoded = fileBuffer.toString(\'base64\')\n // console.log(base64Encoded)\n return base64Encoded\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n您可以像这样获取文件缓冲区:
\n const fileBuffer = fs.readFileSync(path);\n
Run Code Online (Sandbox Code Playgroud)\n或者像这样:
\nconst buf = Buffer.from(\'hey there\');\n
Run Code Online (Sandbox Code Playgroud)\n你还可以使用一个API来为你做编码和编码,这里是一个:
\n要进行编码,您可以传入纯文本作为正文。
\n发布https://mk34rgwhnf.execute-api.ap-south-1.amazonaws.com/base64-encode
\n要解码,请传入 Base64 字符串作为正文。
\n发布https://mk34rgwhnf.execute-api.ap-south-1.amazonaws.com/base64-decode
\n您何时可能需要 Base64 的幻想示例
\n这是一个牵强的场景,说明您何时可能需要使用 Base64。
\n假设你是一名间谍,你的任务是复制一张对你的国家情报部门来说很有价值的照片。
\n该图片位于无法访问互联网且没有打印机的计算机上。你手中只有一支笔和一张纸。没有闪存盘、没有 CD 等。你会做什么?
\n您的第一个选择是将图片转换为二进制 1 和 0 ,将这些 1 和 0 一个一个地复制到纸上,然后运行它。
\n然而,这可能是一个挑战,因为仅使用 1 和 0 作为字母表来表示图片将导致大量的 1 和 0。你的论文很小,你没有时间。另外,1 和 0 越多,出错的可能性就越大。
\n您的第二个选择是使用十六进制而不是二进制。十六进制允许使用 16 个而不是 2 个可能的字符,因此您可以使用更宽的字母表,从而减少所需的纸张和时间。
\n更好的选择是将图片转换为 Base64 并利用另一个更大的字符集来表示数据。更少的纸张和更少的时间来完成。就这样吧!
\nHåv*_*d S 26
专为文本数据设计的媒体当然最终也是二进制文件,但文本媒体通常使用某些二进制值作为控制字符.此外,文本媒体可以拒绝某些二进制值作为非文本.
Base64编码将二进制数据编码为只能在文本媒体中解释为文本的值,并且没有任何特殊字符和/或控制字符,因此数据也将在文本媒体中保留.
Aid*_*ell 17
媒体验证字符串编码更重要,因此我们希望确保处理应用程序可以接受数据(例如,不包含表示EOL的二进制序列)
想象一下,您希望在编码为UTF-8的电子邮件中发送二进制数据 - 如果1和0流创建的序列在UTF-8编码中无效,则电子邮件可能无法正确显示.
当我们想要编码对URL本身中的URL无效的字符时,URL中会发生相同类型的事情:
http://www.foo.com/hello我的朋友 - > http://www.foo.com/hello%20my%20friend
这是因为我们想在系统上发送空间,认为空间有点臭.
我们所做的只是确保已知的良好,可接受和无害的比特序列与另一个字面的比特序列之间存在一对一的映射,并且处理应用程序不区分编码.
在您的示例中,man
可能是第一种形式的有效ASCII; 但通常您可能希望传输随机二进制值(即在电子邮件中发送图像):
MIME-Version:1.0
Content-Description:"a64的base64编码"
内容类型:image/gif; name ="a.gif"
Content-Transfer-Encoding:Base64
Content-Disposition:attachment; 文件名= "A.GIF"
在这里,我们看到GIF图像在base64中编码为电子邮件的一部分.电子邮件客户端读取标头并对其进行解码.由于编码,我们可以确定GIF不包含任何可能被解释为协议的内容,并且我们避免插入SMTP或POP可能发现重要的数据.
Bil*_*ard 12
我发现它很方便的一个例子是尝试在XML中嵌入二进制数据.SAX解析器误解了一些二进制数据,因为这些数据可能实际上是任何东西,包括XML特殊字符.Base64对发送端的数据进行编码并在接收端对其进行解码,解决了这个问题.
Sri*_*bat 11
我将给你一个非常不同但真实的例子:我编写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>
Run Code Online (Sandbox Code Playgroud)
假设我想运行这样的代码:
# ERROR
document.getElementById("/path/to/my_strangely_named_file!@().jpg");
Run Code Online (Sandbox Code Playgroud)
我认为这段代码在执行时会失败.
使用Base64,我可以参考一些复杂的东西,而不必担心哪种语言允许哪些特殊字符和哪些需要转义:
document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");
Run Code Online (Sandbox Code Playgroud)
与使用MD5或其他散列函数不同,您可以反转编码以找出实际有用的数据.
我希望我知道Base64年前.我会避免用encodeURIComponent
'和'撕掉我的头发str.replace(‘\n’,’\\n’)
如果你试图通过ssh传递复杂数据(例如一个dotfile,这样你就可以获得你的shell个性化),祝你好运没有Base 64.这就是你用base 64做的事情(我知道你可以使用SCP,但这会占用多个命令 - 这会使键绑定变得复杂化):
cas*_*nca 10
大多数计算机以8位二进制格式存储数据,但这不是必需的.一些机器和传输介质一次只能处理7位(或甚至更少).这样的介质会以7位的倍数来解释流,因此如果您要发送8位数据,则不会在另一侧收到您期望的内容.Base-64只是解决此问题的一种方法:将输入编码为6位格式,通过介质发送,然后在接收端将其解码为8位格式.
什么是"旨在处理文本数据的媒体"?
这些协议旨在处理文本(通常只有英文文本)而不是二进制数据(如.png和.jpg图像).
他们可以处理二元=>他们可以处理任何事情.
但反过来却不是这样.用于表示文本的协议可能会错误地处理恰好包含以下内容的二进制数据:
因此,您不能仅通过基于文本的协议发送二进制数据.你只限于代表非空间非控制ASCII字符的字节,其中有94个.选择Base 64的原因是它使用2的幂更快,64是最大的工作.
但有一个问题.那些系统如何仍然不同意像常见的UTF-8这样的常见编码技术?
至少在网络上,他们大多数都有. 大多数网站使用UTF-8.
西方的问题是有很多旧软件可以解决1字节= 1个字符并且无法使用UTF-8的问题.
东方的问题是他们对GB2312和Shift_JIS等编码的依恋.
事实上,微软似乎仍然没有选择错误的UTF编码.如果要使用Windows API或Microsoft C运行时库,则限制为UTF-16或区域设置的"ANSI"编码.这使得使用UTF-8变得很痛苦,因为你必须一直转换.
除了其他(有点冗长)答案之外:即使忽略仅支持7位ASCII的旧系统,在文本模式下提供二进制数据的基本问题是:
小智 5
Base64是二进制到文本编码方案之一,具有75%的效率.使用它可以通过传统的"非8位干净"通道安全地发送典型的二进制数据(例如图像).在早期的电子邮件网络中(直到20世纪90年代初),大多数电子邮件消息都是7位US-ASCII字符集中的纯文本.如此多的早期通信协议标准被设计用于"7位"通信链路"非8位清洁".方案效率是输入中的位数与编码输出中的位数之间的比率.十六进制(Base16)也是二进制到文本编码方案之一,效率为50%.