3.1 二进制位的重新分组
Base64 编码的核心思想非常简单:将 3 个 8 位字节(共 24 位)重新分组为 4 个 6 位块。
- 输入: 3 × 8 bit = 24 bits
- 转换: 重新切割
- 输出: 4 × 6 bit = 24 bits
为什么选择 6 位?
因为 2⁶ = 64。一个 6 位二进制数能表示从 0 到 63 的整数,这正好对应了 Base64 字符集中的 64 个字符索引。
3.2 编码步骤详解
让我们以字符串 "ABC" 为例,演示完整的编码过程。
步骤 1:获取原始字节
字符
A
B
C
ASCII
65
66
67
步骤 2:转换为二进制(8位)
A: 01000001
B: 01000010
C: 01000011
连接后 (24位): 010000010100001001000011
步骤 3:按 6 位重新分组
010000 010100 001001 000011
步骤 4 & 5:转十进制并查表
二进制
十进制
索引查表
结果
010000
16
Index 16
Q
010100
20
Index 20
U
001001
9
Index 9
J
000011
3
Index 3
D
3.3 处理非 3 倍数长度的数据
当数据长度不是 3 的倍数时,我们需要在末尾补 0凑齐 6 位,并在编码结果后加 =。
情况 1:输入 "A" (1 字节)
- 二进制:
01000001 - 补 0 凑够 6 位组:
010000(前6位),010000(剩2位+后补4个0) - 十进制:16, 16
- 字符:Q, Q
- 填充:因缺 2 个字节,加两个
= - 结果:QQ==
情况 2:输入 "AB" (2 字节)
- 二进制:
01000001 01000010 - 分组:
010000,010100,001000(剩4位+后补2个0) - 十进制:16, 20, 8
- 字符:Q, U, I
- 填充:因缺 1 个字节,加一个
= - 结果:QUI=
3.4 位运算的具体实现
在编程中,我们通常使用位运算符(>>, <<, &,
|)来实现这一过程。
// 假设 input[0], input[1], input[2] 是三个字节(b1, b2, b3)
// 1. 第一个 6 位:取 b1 的前 6 位
c1 = (b1 >> 2) & 0x3F;
// 2. 第二个 6 位:b1 的后 2 位 + b2 的前 4 位
c2 = ((b1 & 0x03) << 4) | ((b2 >> 4) & 0x0F);
// 3. 第三个 6 位:b2 的后 4 位 + b3 的前 2 位
c3 = ((b2 & 0x0F) << 2) | ((b3 >> 6) & 0x03);
// 4. 第四个 6 位:取 b3 的后 6 位
c4 = b3 & 0x3F;