Base64是一种将二进制编码格式转换为text编码的一种形式。我们知道二进制编码是0和1的形式,它的单位通常是一个字节,也就是8bits,每个bit表示的是0或者1。

而文本编码的格式有很多种,最早也就是最简单的编码格式就是ASCII编码,ASCII编码的全称是American Standard Code for Information Interchange,也就是美国信息交换标准代码,它主要表示的是常用的一些西欧字符。

ASCII的编码范围是0x00-0x7F,用十进制来表示就是0-127,总共128个字符,刚好是7bits表示的范围。

ASCII编码中包含了33个控制字符和95个可打印的字符,如下所示:

Base64就是从ASCII编码中挑选出64个字符和二进制一个字节8bits进行映射,这也就是Base64中64的含义。为什么要选择ASCII编码呢?这是因为ASCII编码是最早出现的编码形式,几乎所有的计算机应用都对其完全支持,不会出现数据传输过程中的内容转换,非常的安全。

当然Base64编码也有多种编码形式,比如在MIME中,Base64选择的是A-Z, a-z, 和 0-9 总共62个字符,再加上其他自选的两个字符组成了64个编码字符。

64个字符用二进制表示是6bits,而常用的二进制使用一个字节来表示,也就是8bits,那么问题来了,怎么将8bits的二进制用6bits的Base64字符来表示呢?

很简单,我们只需要将3个8bits连接起来,变成24bits,这样就可以用4个Base64来表示了。

为什么必须对二进制进行转换呢?这是因为互联网中的某些传输协议只支持某些特定的字符集,如果是其他的字符集是不支持的。比如说常用的发送电子邮件的附件。因为SMTP协议最开始设计的时候是支持7 位 ASCII 字符,所以如果要传输文件的话,我们需要对文件进行编码之后再进行传输。

另外Base64的一种用法就是在HTML中将图片嵌入到网页中,从而实现图片的展示。

虽然Base64很好用,但是因为其只能使用6bits的字符映射集,所以会造成数据映射的损失,从而导致二进制文件编码过后文件体积变大的缺点。

Base64的变体

Base64简单点说就是bit到bit之间的映射,那么肯定不止一种映射方式,我们来看下Base64编码方式的各种变体,通常来说前62位基本上是一样的,不同之处在后面两个字符,以及用于填充的字符(这在某些协议中可能是强制性的,或者在其他协议中可能被删除)。

下表是常见的Base64编码的变体:

Base64的编码细节

上一节我们讲到了Base64编码的基本原则和一些常见的变体,那么到底是如何进行映射的呢?

本节我们会以Base64的标准形式RFC 4648为例来进行详细的讲解。

RFC 4648选择+和/这两个字符作为编码中的第62位和63位,并且选择=作为补全字符。

首先来观察一下RFC 4648的映射表:

我们来以单词man为例,来观察一下Base64的编码流程。

man这个单词在ASCII中分别用77, 97和110表示,转换成为二进制就是01001101, 01100001 和 01101110。

将上面的三个二进制合并在一起就成了:010011010110000101101110, 总共24-bit,从上面的表中选择出对应的字符,所以我们可以得到man经过base64编码之后得到:TWFu。

上面的例子中,man刚好是3个字符,也就是24个bits,可以用base64完整的表示。如果我们只有ma这两个字符,应该怎么进行编码呢?

和上面一样,ma的二进制分别是01001101, 01100001,合并起来就是0100110101100001。

但是上面的bits只有16位,因为一个base64是6bits,所以可以用3个base64来表示,因为原始的bits少了两位,所以用0来补全:

0100110101100001+00 = 010011010110000100。

010011010110000100转换成为base64就是TWE,因为base64编码需要4个字符,所以最后的字符用=来补全,也就是说me经过base64之后变成TWE=。

总结

以上就是Base64的基本含义和转换规则,其实协议很简单,将要转换的数据变成二进制,然后对照转换表格进行转换和补全即可。

作者:flydean
链接:https://www.zhihu.com/question/36306744/answer/2433960035
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。