关于BASE64编码
原理:
准备一个包含64个字符的数组:

对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit
这样我们得到4个数字作为索引,然后查表(上边的数组),获得相应的4个字符,就是编码后的字符串。
所以,Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%。
比如:

如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。


由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种"url safe"的base64编码,其实就是把字符+和/分别变成-和_
由于=字符也可能出现在Base64编码中,但=用在URL、Cookie里面会造成歧义,所以,很多Base64编码后会把=去掉
去掉=后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要在尾部补加上=把Base64字符串的长度变为4的倍数,就可以正常解码了。
综上所述,关于BASE64编码目前主要分三类:
标准的
url safe的,将+和/分别替换为-和_, 是否包含对=号的处理呢?(待求证),但相关知识类库的处理已有不同
去掉=号的
目前在JAVA实现 有以下类库提供了封装
1.java.util.Base64 (JDK自带)
编码:Base64.getEncoder().encodeToString(src);
解码:Base64.getDecoder().decode(str);
2.org.springframework.util.Base64Utils (spring-core包提供,内部调用了JDK自带的)
编码:Base64Utils.encodeToString(src);
解码:Base64.getDecoder().decode(str);
3.org.apache.commons.codec.binary.Base64 (apache commons-codec提供)
编码:Base64.encodeBase64String(src);
解码:Base64.decodeBase64(str);
4.org.osgl.util.Codec (osgl-tool 提供)
Codec.encodeBase64(value);
Codec.decodeBase64(value);
针对URL安全的编码,各大类库的处理不尽相同。
public static void main(String[] args) {
String text = "广铁再增运力保障,计划当日加开34对动车组列车,加油";
byte[] value = text.getBytes();
String s=java.util.Base64.getEncoder().encodeToString(value);
// jdk实现
String s1 = java.util.Base64.getUrlEncoder().encodeToString(value);
// osgl-tool实现
String s2 = Codec.encodeUrlSafeBase64(value);
// apache common-codec实现
String s3 = Base64.encodeBase64URLSafeString(value);
System.out.println("标准BASE64编码:");
System.out.println(s);
System.out.println("URL安全的BASE64编码,分别由jdk,osgl-tool,common-codec实现");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
运行结果如下:

可以看出,URL安全的编码中,已把/替换成_,把+替换成-,至于=号的处理各大类库不尽相同。这个在使用中务必注意。编解码双方必须得统一,否则极其容易出现错误 。

浙公网安备 33010602011771号