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

Base64

Base64 编解码笔记

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


Base64编码过程

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

2、对二进制数据进行处理,每 3 个字节一组,一共是 3x8=24bit,划为 4 组,每组正好 6 个 bit, 这样我们得到 4 个 [0,63] 范围内的数字作为索引,然后查表,获得相应的 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


Linux base64命令

对文件、标准输入进行 base64 编解码,并打印到标注输出

-d, –decode 解码数据
-i, –ignore-garbag 解码时忽略非字母字符
-w, –wrap=字符数 在指定的字符数后自动换行(默认为76),0 为禁用自动换行
–version 显示版本信息并退出

如果没有指定文件,或者文件为”-“,则从标准输入读取。

数据以 RFC 3548 规定的 Base64 字母格式进行编码。 解码时,输入数据(加密流)可能包含一些非有效 Base64 字符的新行字符。可以尝试用 –ignore-garbage 选项来恢复加密流中任何非 base64 字符。

base64 从标准输入中读取数据,按Ctrl+D结束输入。将输入的内容编码为base64字符串输出。

echo "str" | base64 将字符串 str+换行 编码为base64字符串输出。
echo -n "str" | base64 将字符串str编码为base64字符串输出,最后没有换行。注意与上面的差别。

base64 file 从指定的文件file中读取数据,编码为base64字符串输出。

base64 -d 从标准输入中读取已经进行base64编码的内容,解码输出。

base64 -d -i 从标准输入中读取已经进行base64编码的内容,解码输出。加上-i参数,忽略非字母表字符,比如换行符。

echo "str" | base64 -d 将base64编码的字符串str+换行 解码输出。
echo -n "str" | base64 -d 将base64编码的字符串str解码输出,最后没有换行。注意与上面的差别。

base64 -d file 从指定的文件file中读取base64编码的内容,解码输出。


Spring提供的Base64Utils工具类

public static String encodeToString(byte[] src)


commons-codec提供的Base64工具类

public static String encodeBase64String(final byte[] binaryData)


Hex十六进制转babse64

在线hex转base64

方法一 在线工具
打开这个在线工具 https://the-x.cn/zh-cn/base64
“常规base64”,填入 十六进制 值(注意开头的0x要去掉),“编码源格式” 选择 Hex 转 base64,点击“编码”,得到 base64 编码的十六进制。

java hex转base64

方法二 java 代码
写个 java 代码单测,使用 commons-lang-codec 的 Hex 工具类把十六进制字符串转为 byte 数组,再用 spring-core 的 Base64Utils 转换为 base64

@Test
public void hexoToByteArray() throws Exception {
    byte[] bytes = Hex.decodeHex("4E6AE63D".toCharArray());
    System.out.println("base64:");
    System.out.println(Base64Utils.encodeToString(bytes));
}

上一篇 护肤

下一篇 JaCoCo

阅读
评论
1,465
阅读预计6分钟
创建日期 2020-10-28
修改日期 2021-01-07
类别
标签

页面信息

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

评论