概述
Base64是一种字符串编码格式,能将任意Binary资料用64种字元组合(A-Z a-z 0-9 “+“ “/“(还有垫字符“=“)成字串的方法,一个字符本身是1个字节,也就是8位,而Base64编码后的一个字符只能表示能表示6位的信息。也就是原始字符串中3字节的信息编码会变成4字节的信息。Base64的主要作用是满足MIME传输需求,在传输过程中都是用ASCII支持的可见字符。Base64是基于字节的编码,所以不同字符集下的相同字符在Base64下可能有着不同编码。
问题描述
在经过BASE64编码后的字符串,通过接口传输到其它外部程序无法解码
将BASE64编码后的字符串输出后发现字符串中存在换行符
测试程序
早期使用Java做Base64的编码与解码,会使用到JDK里sun.misc下的BASE64Encoder和BASE64Decoder这两个类(编码和解码的效率不太好),用法如下:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Base64MainTest {
public static void main(String[] args) throws Exception {
String message = "testBase64&com.sun.org.apache.xml.internal.security.utils.Base64";
//编码
String base64String = new BASE64Encoder().encodeBuffer(message.getBytes());
System.out.println(base64String);
//解码
byte[] base64 = new BASE64Decoder().decodeBuffer(base64String);
System.out.println(new String(base64));
}
}
程序输出
dGVzdEJhc2U2NCZjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LnV0aWxz
LkJhc2U2NA==
观察测试结果
- base64编码后出现了换行符
- 如果去除换行符,其它外部程序无法解码字符串能正常解码
原因分析
Base64编码包有很多,内外部程序使用了不同标准的Base64编码包,稍不注意可能会得不到期望的结果引起bug。
根据RFC822规定,BASE64Encoder编码每76个字符,还需要加上一个回车换行
部分Base64编码的java库还按照这个标准实行
sun.mis包:encode有换行符
Java 8的java.util包:encode无换行符
Apache Commons Codec:encode无换行符
解决方案
1.换用Apache的 commons-codec.jar
maven坐标:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
使用到org.apache.commons.codec.binary套件下的Base64类别,Base64.encodeBase64String(byte[])得到的编码字符串是不带换行符的,用法如下:
import org.apache.commons.codec.binary.Base64;
public class Base64MainTest {
public static void main(String[] args) {
String message = "testBase64&com.sun.org.apache.xml.internal.security.utils.Base64";
//编码
String base64String = Base64.encodeBase64String(message.getBytes());
System.out.println(base64String);
//解码
byte[] base64 = Base64.decodeBase64(base64String);
System.out.println(new String(base64));
}
}
2.Java 8之后的作法
Java 8的java.util包中,新增了Base64的类别,可以用来处理Base64的编码与解码,用法如下:
import java.util.Base64;
public class Base64MainTest {
public static void main(String[] args) {
String message = "testBase64&com.sun.org.apache.xml.internal.security.utils.Base64";
//编码
String encodeToString = Base64.getEncoder().encodeToString(message.getBytes());
System.out.println(encodeToString);
//解码
byte[] decode = Base64.getDecoder().decode(encodeToString);
System.out.println(new String(decode));
}
}
与sun.mis包和Apache Commons Codec所提供的Base64编解码器比较,Java 8提供的Base64拥有更好的效能。实际测试编码与解码速度的话,Java 8提供的Base64,要比sun.mis包提供的还要快至少11倍,比Apache Commons Codec提供的还要快至少3倍。因此在Java上若要使用Base64,Java 8的java .util包所提供的Base64类是首选!
参考地址:
Base64编码出现换行符_月光轩辕的专栏-CSDN博客_base64 换行
Java如何进行Base64的编码(Encode)与解码(Decode)_霓虹深处-CSDN博客_encodebase64string