5.4 实现原理
Base64算法主要是将给定的字符以与字符编码(如ASCII码,UTF-8码)对应的十进制数为基准,做编码操作:
1)将给定的字符串以字符为单位,转换为对应的字符编码(如ASCII码)。
2)将获得的字符编码转换为二进制码。
3)对获得的二进制码做分组转换操作,每3个8位二进制码为一组,转换为每4个6位二进制码为一组(不足6位时低位补0)。这是一个分组变化的过程,3个8位二进制码和4个6位二进制码的长度都是24位(3×8=4×6=24)。
4)对获得的4-6二进制码补位,向6位二进制码添加2位高位0,组成4个8位二进制码。
5)将获得的4-8二进制码转换为十进制码。
6)将获得的十进制码转换为Base64字符表中对应的字符。
5.4.1 ASCII码字符编码
我们对字符串“A”进行Base64编码,如下所示:
字符 A
ASCII码 65
二进制码 01000001
4-6二进制码 010000 010000
4-8二进制码 00010000 00010000
十进制码 16 16
字符表映射码 Q Q==
由此,字符串“A”经过Base64编码后就得到了“QQ==”这样一个字符串。
Base64解码操作就是编码操作的逆运算,反推上述流程很容易获得原文信息,本文不做详述。
作者有意选择了这样一个字符串作为Base64编码,它经过Base64编码后的字符串末尾带着2个等号。很显然,当原文的二进制码长度不足24位,最终转换为十进制码时也不足4项,这时就需要用等号补位。如果原文只有一个字符,那么经过Base64编码后的字符串末尾会有2个等号。
经Base64编码后的字符串最多只会有2个等号,这是因为:
余数=原文字节数MOD 3
这是一个简单的算术问题,余数的值只可能是0、1或2。余数为0时,则原文字节数恰好是3的倍数,没有等号这个尾巴;余数为1时,则为了让Base64编码后的字符数是4的倍数,要补2个等号;同理,余数为2时,则要补1个等号。所以,通常判别一个字符串是不是Base64编码的第一步操作就是判断这个字符串末尾是不是有等号。
这同时也说明,Base64编码后的字符串是以4个字符为单位,其长度只能是4个字符的整数倍。本文开篇对“Java加密与解密的艺术”这个字符串做了Base64编码后获得了一个长度为40个字符的字符串“SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==”,正好说明了这一点。