第三章

Base64 编码的数学原理

从二进制位(Bit)层面深入剖析转换过程

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;