Java 的三种 Base64

tldr;

Base64.Decoder decoder = Base64.getDecoder(); -> new String(decoder.decode("base64 string"), "UTF-8");
Base64.Encoder encoder = Base64.getEncoder();  -> encoder.encodeToString(byte[])
  1. sun: final BASE64Encoder encoder = new BASE64Encoder();
  2. apache: final Base64 base64 = new Base64();
  3. jdk8: final Base64.Decoder decoder = Base64.getDecoder();

0. 定义: 二进制文件可视化

Base64 是一种能将任意二进制文件用 64 种字元组合成字串的方法, 彼此之间是可以互相转换的. 也常用来表示字串加密后的内容, 例如电子邮件 (很多文本混杂大量 +, /, A-Z, a-z, 0-9, =,一看就知道是 Base64 编码后的字符, 其中 eyJh 开头的很明显, 代表 {"[a-zA-Z0-9] 开头的 json 字符)

Base64 编码步骤:

第一步,将每三个字节作为一组,一共是24个二进制位

第二步,将这24个二进制位分为四组,每个组有6个二进制位 (因为 6 位 2 进制最大数为 63)

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节 (每 3 个字节, 增加 1 个字节: ceil(n / 3) * 4)

第四步,根据序号表(0-63),得到扩展后的每个字节的对应符号就是Base64的编码值

Base64 encoding causes an overhead of 33–37% relative to the size of the original binary data (33% by the encoding itself; up to 4% more by the inserted line breaks).

1. sun.misc.BASE64Decoder 包下的 BASE64Encoder

早期在 Java 上做 Base64 的编码与解码, 会使用到 JDK 里的 sun.misc 套件下的 BASE64Encoder 和 BASE64Decoder 这两个类, 缺点是编码和解码的效率不高

final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));

2. org.apache.commons.codec.binary.Base64 包下的 Base64

比 sun 包更精简,实际执行效率高不少, 缺点是需要引用 Apache Commons Codec, 但 tomcat 容器下开发, 一般都自动引入可直接使用.

final Base64 base64 = new Base64();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = base64.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(base64.decode(encodedText), "UTF-8"));

3. java.util 包下的 Base64 (JDK 8 推荐)

java 8 的 java.util 包下 Base64 类, 可用来处理 Base64 的编码与解码

final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));

Java 8 提供的 Base64 效率最高. 实际测试编码与解码速度, Java 8 的 Base64 要比 sun包下的要快大约 11 倍,比 Apache 的快大约 3 倍.

生成 url safe 的 base64 编码

url 中特定字符会被 url encoding, base64 所使用的字符, 占了3个: +, /, =;

处理方法:

  • + 替换为 -
  • / 替换为 _
  • 移除末尾的 = 填充符

jdk8+, 有专门的方法: getUrlEncoder, getUrlDecoder;

String url = Base64.getUrlEncoder().withoutPadding().encodeToString("text".getBytes("utf-8"));

4. 补充

4.1 shell 下的 base64 加密/解码

命令: base64

# 解码
echo 'ZmVmZWFqaXppamZlamlm' |base64 --decode
# -d or -D or --decode
# 当不以换行符结尾时, 解码会带有 %

# 加密
echo -n 'fefeajizijfejif' |base64
# -n Do not print the trailing newline character 不打印尾随换行符

4.2 js 下的 base64 加密/解密 (最常用)

使用时, 打开浏览器的 F12 控制台即可

// 加密
> window.btoa("base64#encode#string")
< YmFzZTY0I2VuY29kZSNzdHJpbmc=

// 解密
> window.atob("YmFzZTY0I2VuY29kZSNzdHJpbmc=")
< base64#encode#string

记: 解密 -> atob (用的最多的也是解密); 从时间顺序来说, 先加密才有解密, 所以相对于 btoa -> atob 是逆序

4.3 浏览器查看base64图片/PDF

URL 框填入: data:文件类型;base64,base64字符串

  • PDF
data:application/pdf;base64,
  • 图片
data:image/jpeg;base64,
  • 文字
data:text/plain;base64,aGVsbG8gd29ybGQ=
  • 更多文件类型见:
org.springframework.http.MediaType;
org.springframework.util.MimeTypeUtils;

后面再加上 base64 加密后的字符串, 回车

或者以文件形式下载

window.open("data:application/octet-stream;base64," + "base64_code...")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值