DS&A - Base64

文章目录


前言

Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 log ⁡ 2 64 = 6 \log_{2}64=6 log2​64=6,所以每 6 比特为一个单元,对应某个可打印字符
3 个字节相当于 24 个比特,对应于 4 个 Base64 单元,即 3 个字节可由 4 个可打印字符来表示。在 Base64 中的可打印字符包括字母 A-Z、a-z、数字 0-9,这样共有 62 个字符,此外两个可打印符号在不同的系统中而不同。
一些如 uuencode 的其他编码方法,和之后 BinHex 的版本使用不同的 64 字符集来代表 6 个二进制数字,但是不被称为 Base64。

以上是*对 Base64 的描述。也就是说 Base64 是一种二进制到文本的编码方式,而且该文本只包含 ASCII 的可见字符

索引表

数值 字符 数值 字符 数值 字符 数值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

原理

DS&A - Base64

如上图所示,字符串 hello 经过 Base64 编码则生成 aGVsbG8=,ASCII 字符不足则 Base64 用 0 比特补足,若 Base64 单元不为 4 的倍数也用 0 比特补足,但展示为 =, 表示为填充位。

对应 Java 代码为:

// JDK 17
var arr = "hello".getBytes(StandardCharsets.UTF_8);
var ints = new ArrayList<Integer>(arr.length);
for (byte b : arr) {
    ints.add(b & 0xFF);
}
ints.stream()
        .map(b -> Integer.toBinaryString(b & 0xFF))
        .map(s -> String.format("%8s", s).replace(' ', '0'))
        .forEach(System.out::println);

var base64 = Base64.getEncoder().encodeToString(arr);
System.out.println(base64);

输出如下:

01101000
01100101
01101100
01101100
01101111
aGVsbG8=

解决问题

从 Base64 的定义中我们可以知道,Base64 把所有不可见字符都转为可见字符了,那么 Base64 主要也就是处理文本协议在传输过程中不可见字符的问题了。在网络交换数据的时候,数据需要经过多个路由设备,由于不同设备处理对不可见字符处理的不同,可能出现错误的处理,这是不利于传输的,于是乎就出现 Base64 这样的编码方式。

上一篇:04-C. DS双向链表—祖玛


下一篇:第七章-DS-B树/B+树