Base64编码出现换行符

概述

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

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值