维基百科上说

当需要对二进制数据进行编码时,通常使用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

以传输相同数量信息的更多数据为代价,确保接收者能够以预期的方式解码数据,即使接收者对其余字符集有不同的解释。


当前回答

大多数计算机以8位二进制格式存储数据,但这不是必需的。一些机器和传输介质一次只能处理7位(甚至更少)。这样的介质将以7位的倍数来解释流,因此如果您要发送8位的数据,您将不会在另一端收到您所期望的内容。Base-64只是解决这个问题的一种方法:将输入编码为6位格式,通过媒体发送,然后在接收端解码回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可能认为重要的数据。

下面是我看了别人贴出来的东西后的理解总结:

重要!

Base64编码并不意味着提供安全性

Base64编码不是用来压缩数据的

为什么使用Base64

Base64是数据的文本表示形式,仅由64个字母数字字符(小写和大写)、+、/和=组成。 这64个字符被认为是“安全的”,也就是说,与<、> \n和许多其他字符不同,它们不会被传统计算机和程序误解。

什么时候Base64有用

我发现base64在以文本形式传输文件时非常有用。获取文件的字节并将它们编码为base64,传输base64字符串,从接收端执行相反的操作。

这与在电子邮件期间通过SMTP发送附件时使用的过程相同。

如何执行base64编码/解码

从base64文本到字节的转换称为解码。 从字节到base64文本的转换称为编码。这与其他编码/解码的命名方式略有不同。

Dotnet 和 Powershell

微软的Dotnet框架支持将字节编码和解码到base64。在mscorlib库中查找Convert名称空间。

下面是你可以使用的powershell命令:

// Base64 encode PowerShell 
// See: https://adsecurity.org/?p=478
$Text='This is my nice cool text'
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$EncodedText = [Convert]::ToBase64String($Bytes)
$EncodedText


// Convert from base64 to plain text 
[System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('VABoAGkAcwAgAGkAcwAgAG0AeQAgAG4AaQBjAGUAIABjAG8AbwBsACAAdABlAHgAdAA='))
Output>This is my nice cool text 

Bash有一个内置的base64编码/解码命令。你可以这样使用它:

编码到base64:

echo 'hello' | base64

解码base64编码的文本为普通文本:

echo 'aGVsbG8K' | base64 -d

Node.js也支持base64。下面是一个你可以使用的类:


/**
 * Attachment class.
 * Converts base64 string to file and file to base64 string
 * Converting a Buffer to a string is known as decoding.
 * Converting a string to a Buffer is known as encoding.
 * See: https://nodejs.org/api/buffer.html
 * 
 * For binary to text, the naming convention is reversed.
 * Converting Buffer to string is encoding.
 * Converting string to Buffer is decoding.
 *  
 */
class Attachment {
    constructor(){

    }

    /**
     * 
     * @param {string} base64Str 
     * @returns {Buffer} file buffer
     */
    static base64ToBuffer(base64Str) {
        const fileBuffer = Buffer.from(base64Str, 'base64');
        // console.log(fileBuffer)
        return fileBuffer;
    }

    /**
     * 
     * @param {Buffer} fileBuffer 
     * @returns { string } base64 encoded content
     */
    static bufferToBase64(fileBuffer) {
        const base64Encoded = fileBuffer.toString('base64')
        // console.log(base64Encoded)
        return base64Encoded
    }
}

你会得到这样的文件缓冲区:

  const fileBuffer = fs.readFileSync(path);

或像这样:

const buf = Buffer.from('hey there');

你也可以使用API为你做编码和编码,这里有一个:

要进行编码,需要传入纯文本作为主体。

文章https://mk34rgwhnf.execute - api.ap -南- 1. - amazonaws.com/base64编码

要解码,传入base64字符串作为主体。

文章https://mk34rgwhnf.execute - api.ap -南- 1. - amazonaws.com/base64解码

幻想的例子,当你可能需要base64

这里是一个牵强附会的场景,您可能需要使用base64。

假设你是一名间谍,你的任务是复制并拿回一张有价值的照片,带回你国家的情报机构。

这张照片是在一台不能上网也没有打印机的电脑上拍摄的。你手里只有一支笔和一张纸。没有闪盘,没有CD等等。你会怎么做?

你的第一个选择是把图片转换成二进制的1和0,把这些1和0一个一个地复制到纸上,然后跑过去。

然而,这可能是一个挑战,因为只使用1和0作为字母表来表示一张图片会导致很多1和0。你的纸太小了,你没有时间。另外,1和0越多,出错的几率就越大。

第二个选择是使用十六进制而不是二进制。十六进制允许16个而不是2个可能的字符,所以你有一个更宽的字母表,因此更少的纸张和时间所需。

更好的选择是将图片转换为base64,并利用另一个更大的字符集来表示数据。更少的纸和更少的时间来完成。好了!

为文本数据设计的媒体当然最终也是二进制的,但是文本媒体通常使用某些二进制值作为控制字符。此外,文本媒体可能会拒绝某些二进制值作为非文本。

Base64编码将二进制数据编码为只能在文本媒体中解释为文本的值,并且不包含任何特殊字符和/或控制字符,因此数据也可以在文本媒体中保存。

我发现方便的一个例子是尝试在XML中嵌入二进制数据。SAX解析器错误地解释了一些二进制数据,因为这些数据可以是任何东西,包括XML特殊字符。Base64在发送端对数据进行编码,在接收端对其进行解码,解决了这个问题。

大多数计算机以8位二进制格式存储数据,但这不是必需的。一些机器和传输介质一次只能处理7位(甚至更少)。这样的介质将以7位的倍数来解释流,因此如果您要发送8位的数据,您将不会在另一端收到您所期望的内容。Base-64只是解决这个问题的一种方法:将输入编码为6位格式,通过媒体发送,然后在接收端解码回8位格式。