BASE64编码

参考
如何用通俗易懂的语言解释base64?
Base64编码原理与应用
base64 前世今生
为什么要使用base64编码,有哪些情景需求?

早期的计算机天才们,为了表示他们国家的语言,26个英文字符,数字,还有一些特殊符号,发明了ASCII编码,如果直译英文,则是:为了信息交换而制定的一套美国标准编码。注意里面的“交换”二字。当ASCII编码问世之后,使用英文的国家爽了,往计算机里面写入信息,就是写自己国家的语言。但随着计算机的普及,其他国家也开始使用计算机,可是,有很多国家不使用英文,比如:中国、俄国、日本、韩国等,ASCII编码显然不能满足。 那怎么办?Unicode、GBK、GB2132等编码出现了。麻烦是不是又来了? 是的。 随着计算机网络的发明,到网络的普及,各国的计算机系统需要交流,此时各个计算机系统可能使用的是不同编码,那如何解决这个问题呢?在计算机里面,有一个通用的解决问题的方法:加一个中间层,Base64就是一个中间层。当我们通过网络传输中文的时候,先用Base64编码,传输到特定终端之后,再用Base64解码,这样就解决了可能出现的乱码问题。

一、BASE64算法原理

Base64编码之所以称为Base64,是因为其使用64个字符来对任意数据进行编码,同理有Base32、Base16编码。标准Base64编码使用的64个字符为:

 

BASE64编码

image.png

 

Base64编码本质上是一种将二进制数据转成文本数据的方案。对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次方=64)计算其十进制值,根据该值在上面的索引表中找到对应的字符,最终得到一个文本字符串。

假设我们要对 Hello! 进行Base64编码,按照ASCII表,其转换过程如下图所示:

BASE64编码

image.png


可知 Hello!的Base64编码结果为 SGVsbG8h ,原始字符串长度为6个字符,编码后长度为8个字符,每3个原始字符经Base64编码成4个字符,编码前后长度比4/3,这个长度比很重要 - 比原始字符串长度短,则需要使用更大的编码字符集,这并不我们想要的;长度比越大,则需要传输越多的字符,传输时间越长。Base64应用广泛的原因是在字符集大小与长度比之间取得一个较好的平衡,适用于各种场景。

 

是不是觉得Base64编码原理很简单?

但这里需要注意一个点:Base64编码是每3个原始字符编码成4个字符,如果原始字符串长度不能被3整除,那怎么办?使用0值来补充原始字符串。

Hello!!为例,其转换过程为:

BASE64编码

图表中蓝色背景的二进制0值是额外补充的


Hello!!Base64编码的结果为 SGVsbG8hIQAA 。最后2个零值只是为了Base64编码而补充的,在原始字符中并没有对应的字符,那么Base64编码结果中的最后两个字符 AA 实际不带有效信息,所以需要特殊处理,以免解码错误。

 

标准Base64编码通常用 = 字符来替换最后的 A,即编码结果为 SGVsbG8hIQ==。因为 = 字符并不在Base64编码索引表中,其意义在于结束符号,在Base64解码时遇到 = 时即可知道一个Base64编码字符串结束。

如果Base64编码字符串不会相互拼接再传输,那么最后的 = 也可以省略,解码时如果发现Base64编码字符串长度不能被4整除,则先补充 = 字符,再解码即可。

解码是对编码的逆向操作,但注意一点:对于最后的两个 = 字符,转换成两个 A 字符,再转成对应的两个6比特二进制0值,接着转成原始字符之前,需要将最后的两个6比特二进制0值丢弃,因为它们实际上不携带有效信息。

二、为什么是64而不是其他呢?

我们知道64是2的6次方,一连串二进制被6位6位的等分

那为什么不是5位等分或者7位等分呢?

7位等分就需要128个字符,找不到这么多现成的字符,而5位等分只需要32个字符,连大小写字符都没用完,太浪费了

6等分造成的一个后果就是 base64 后的文本大小始终是大于等于源数据的 8/6,也就是至少比源文件大 1/3,那也肯定比源数据大的,因为虽然6等分了,但一个字符还是8bit。但要注意的是 gzip 后这个大小差距会减少

三、Base 64作用

Base 64 Encoding有什么用?举个简单的例子,你使用SMTP协议 (Simple Mail Transfer Protocol 简单邮件传输协议)来发送邮件。因为这个协议是基于文本的协议,所以如果邮件中包含一幅图片,我们知道图片的存储格式是二进制数据(binary data),而非文本格式,我们必须将二进制的数据编码成文本格式,这时候Base 64 Encoding就派上用场了。
具体参考Laya Image 图集

四、是编码,并不是加密

很多人都以为编码(Encoding)和加密(Encryption)是同一个意思。编码和加密都是对格式的一种转换,但是它们是有区别的。编码是公开的,比如的Base 64编码,任何人都可以解码;而加密则相反,你只希望自己或者特定的人才可以对内容进行解密。
很多博客什么的都把Base64当做加密算法,这是不对的。Base64不具有可读性,但不代表这个编码是加密的。加密需要保证,没有**的人无法解密信息,无法从密文中获得任何明文信息。Base64编码显然没有**什么事… 所以,这个误区大家要纠正过来。