当前位置 : 首页 » 文章分类 :  开发  »  Base64

Base64

Base64编解码笔记

Base64 是一种用 64 个字符来表示任意二进制数据的方法。


Base64编码过程

1、准备一个包含 64 个字符的数组作为码表
['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']

2、对二进制数据进行处理,每 3 个字节一组,一共是 3x8=24bit,划为 4 组,每组正好 6 个 bit, 这样我们得到 4 个数字作为索引,然后查表,获得相应的 4 个字符,就是编码后的字符串。

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

所以,Base64 编码会把 3 字节的二进制数据编码为 4 字节的文本数据,长度增加 33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。

URL safe 的Base64编码

由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种”url safe”的base64编码,其实就是把字符+和/分别变成-和_


Java原生的Base64编解码工具类

Java 8 在 java.util 包中新增了 Base64 编解码类,直接就可以用。

java.util.Base64 包括下面三种 Base64 编解码器
1 Basic编码
2 URL编码
3 MIME编码

Basic 编解码

Basic 编码是标准的 BASE64 编码,用于处理常规的需求:输出的内容不添加换行符,而且输出的内容由字母加数字组成。

URL 编解码

由于 URL 对斜线 / 有特殊的意义,因此 URL 编码需要替换掉它,使用下划线 _ 替换。
URL 编解码器和 Basic 的不同就在于会将编码后的结果中的 / 替换为 _

MIME 编解码

MIME 编解码器和 Basic 的不同在于会自动换行,每行不超过 76 个字符,自动用 \r\n 分割以实现换行。但是结果中还是会有 /

@Test
public void testBase64Codec() {
    System.out.println("Basic 编解码");
    String basic = Base64.getEncoder().encodeToString("subjects?abcd".getBytes(StandardCharsets.UTF_8));
    System.out.println(basic);
    System.out.println(new String(Base64.getDecoder().decode(basic), StandardCharsets.UTF_8));

    System.out.println("\nURL 编解码");
    String url = Base64.getUrlEncoder().encodeToString("subjects?abcd".getBytes(StandardCharsets.UTF_8));
    System.out.println(url);
    System.out.println(new String(Base64.getUrlDecoder().decode(url), StandardCharsets.UTF_8));

    System.out.println("\nMIME 编解码");
    String mime = Base64.getMimeEncoder().encodeToString(("subjects?abcdsubjects?abcdsubjects?abcdsubjects?abc" +
            "dsubjects?abcdsubjects?abcdsubjects?abcd").getBytes(StandardCharsets.UTF_8));
    System.out.println(mime);
    System.out.println(new String(Base64.getMimeDecoder().decode(mime), StandardCharsets.UTF_8));
}

结果

Basic 编解码
c3ViamVjdHM/YWJjZA==
subjects?abcd

URL 编解码
c3ViamVjdHM_YWJjZA==
subjects?abcd

MIME 编解码
c3ViamVjdHM/YWJjZHN1YmplY3RzP2FiY2RzdWJqZWN0cz9hYmNkc3ViamVjdHM/YWJjZHN1Ympl
Y3RzP2FiY2RzdWJqZWN0cz9hYmNkc3ViamVjdHM/YWJjZA==
subjects?abcdsubjects?abcdsubjects?abcdsubjects?abcdsubjects?abcdsubjects?abcdsubjects?abcd

封装输入输出流

编码器封装输出流,将给定字符串编码为 Base64 后写入文件输出流
解码器封装输入流,对 Base64 编码的文件流进行解码

@Test
public void wrapStreamTest() throws Exception {
    // 创建的文件是 target/test-classes/file-base64.txt
    File file = new File(this.getClass().getResource("/").getPath() + "file-base64.txt");
    try (
            // 编码器封装输出流,将给定字符串编码为 Base64 后写入文件输出流
            OutputStream os = Base64.getEncoder().wrap(new FileOutputStream(file));
    ) {
        IOUtils.write(System.getProperties().toString(), os, StandardCharsets.UTF_8);
    }

    try (
            // 解码器封装输入流,对 Base64 编码的文件流进行解码
            InputStream is = Base64.getDecoder().wrap(new FileInputStream(file))
    ) {
        IOUtils.readLines(is, StandardCharsets.UTF_8).forEach(System.out::println);
    }
}

Java 8实现BASE64编解码
http://masikkk.com/article/Java-Basic/#base64-%E7%BC%96%E7%A0%81


Spring提供的Base64Utils工具类

public static String encodeToString(byte[] src)


commons-codec提供的Base64工具类

public static String encodeBase64String(final byte[] binaryData)


上一篇 护肤

下一篇 JaCoCo

阅读
评论
889
阅读预计4分钟
创建日期 2020-10-28
修改日期 2020-10-28
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论