最近处理几个集成OAuth20接口,遇到关于计算 Base64 的问题,记录一下。
使用 Java 进行 Base64 计算时候,有许多第三方库可以使用,JDK 自带了两种:
- sun.misc.BASE64Encoder
- java.util.Base64
分别使用如下:
sun.misc.BASE64Encoder
public String encodeBySun(String str) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(str.getBytes());
}
java.util.Base64
public String encodeByJDK(String str) {
return Base64.getEncoder().encodeToString(str.getBytes());
}
当要计算字符串 str 长度不长时,二者返回数据一致,当 str 较长会导致计算结果也变长,二者计算结果不一致
String[] strArr = {
"asdasdasdasdasdasdasdasdasdsdasdadasasdasdasdasdasdasda",
"asdasdasdasdasdasdasdasdasdsdasdadasasdasdasdasdasdasdasdsdsdsds"
};
for (String s : strArr) {
System.out.println("========================");
System.out.println("originStr:");
System.out.println(s);
System.out.println("BASE64Encoder:");
System.out.println(encodeBySun(s));
System.out.println("Base64:");
System.out.println(encodeByJDK(s));
}
结果如下:
========================
originStr:
asdasdasdasdasdasdasdasdasdsdasdadasasdasdasdasdasdasda
BASE64Encoder:
YXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkc2Rhc2RhZGFzYXNkYXNkYXNkYXNkYXNkYXNkYQ==
Base64:
YXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkc2Rhc2RhZGFzYXNkYXNkYXNkYXNkYXNkYXNkYQ==
========================
originStr:
asdasdasdasdasdasdasdasdasdsdasdadasasdasdasdasdasdasdasdsdsdsds
BASE64Encoder:
YXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkc2Rhc2RhZGFzYXNkYXNkYXNkYXNkYXNkYXNkYXNk
c2RzZHNkcw==
Base64:
YXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkYXNkc2Rhc2RhZGFzYXNkYXNkYXNkYXNkYXNkYXNkYXNkc2RzZHNkcw==
当结果超过76个字符时 BASE64Encoder
会自动添加新的一行。但是我们本意并不想这样,从而造成开发中的困扰。
查询相关资料:
- https://mathematica.stackexchange.com/questions/100509/why-base64-ends-with-a-newline-n
- https://stackoverflow.com/questions/19952621/is-it-ok-to-remove-newline-in-base64-encoding
- https://www.ietf.org/rfc/rfc2045.txt
大致整理有的原因说 BASE64Encoder 为了兼容老的计算机程序读取数据,从而添加换行;也有说二者遵循的 RFC 不同,BASE64Encoder 遵循的是 RFC 2045,要求加入换行,Base64默认使用遵循 RFC4648 的 encoder,如果想使用 RFC2045,可以使用 Base64.getMimeEncoder()
当然这些都是小事儿,了解了就行了。后来测试当字符串较长的时候 Base64
的性能要好于 BASE64Encoder
。