Base64简介
首先我需要澄清一点,Base64并不是一种加密的方法,而是一种编码的方式。虽然用Base64加密(暂且说是加密)的字符串看起来有一种被加密的感觉,但是这只是感觉。
因为如果用标准的Base64进行加密会发现很多Base64的特征,比如在Base64字符串中会出现'+'和'\'两种字符,在字符串的末尾经常会有一个到两个连续的'='。
只要发现了这些特征,就可以肯定这个字符串被Base64加密过,只要通过相应的解密小程序就可以轻松得到加密前的样子(非标准的除外)。
那么又为什么说Base64是一种编码方式呢?这是因为Base64可以把所有的二进制数据都转换成ASCII码可打印字符串的形式(制表符,空格等为不可打印)。以便在只支持文本的环境中也能够顺利地传输二进制数据。
编码原理
Base64编码的核心原理是将二进制数据进行分组,每24Bit(3字节)为一个大组,再把一个大组的数据分成4个6Bit的小分组。
由于6Bit数据只能表示64个不同的字符(2^6=64),所以这也是Base64的名字由来。
这64个字符分别对应ASCII码表中的'A'-'Z','a'-'z','0''9','+'和'/'。他们的对应关系是由Base64字符集决定的。
因为小分组中的6Bit数据表示起来并不方便,所以要把每个小分组进行高位补零操作,这样每个小分组就构成了一个8Bit(字节)的数据。
在补零操作完成后接下来的工作就简单多了,那就是将小分组的内容作为Base64字符集的下标,然后一一替换成对应的ASCII字符。加密工作完成。
Base64解密的工作原理也非常的简单,只要操作方式和加密步骤相反即可。首先将Base64编码根据其对应的字符集转换成下标,这就是补完零后的8Bit(一字节)数据。
既然有补零操作那自然会有去零操作了,我们要将这些8Bit数据的最高位上的两个0抹去形成6Bit数据,这也就是前面我们提到过的小分组。
最后就是将每4个6Bit数据进行合并形成24Bit的大分组,然后将这些大分组按照每组8Bit进行拆分就会得到3个8Bit的数据,这写8Bit数据就是加密前的数据了。解密工作完成。
重点:别看前面说的Base64工作流程这么简单,实际上里面还是有很多坑的,那在我们了解了编码原理后现在就来填坑了:
我们在Base64编码前是无法保证准备编码的字符串长度是3的倍数,所以为了让编码能够顺利进行就必须在获取编码字符串的同时判断字符串的长度是否是3的倍数。
如果是3的倍数编码就可以正常进行,如果不是那么就要进行额外的操作------补零,就是要在不足3的倍数的字符串末尾用0x00进行填充。
这样就是解决了字符串长度不足的问题了,但是同时也引进了另一个新的问题,那就是末尾补充上的0在进行Base64字符集替换的时候会与字符集中的'A'字符发生冲突。
因为字符集中的下标0对应的字符是'A',而末尾填充上的0x00在分组补零后同样是下标0x00,这样就无法分辨出到底是末尾填充的0x00还是二进制数据中的0x00。
为了解决这个问题我们就必须引入Base64字符集外的新字符来区分末尾补充上的0x00,这就是'='字符不在Base64字符集中,但是也出现在Base64编码的原因了,'='字符在一个Base64编码的末尾中最多会出现两个,如果不符合这以规则那么这个Base64就可能被人做了手脚。
Base64字符集:
Base64的编码图解
1、判断字符串长度,不足3的倍数用0x00填充
2、将补零后的字符串进行8Bit分组
3、把每个大分组进行6Bit分组
4、将6Bit组转换成Base64字符集的下标
注:由于是进行图片解说,所以省区了6Bit组高位补零操作
5、把字符集的下标替换成Base64字符
6、修正末尾的符号,得到Base64编码结果
解密操作和加密操作相反!