密码学(二):base64原理

在网络编程和后端开发中,我们经常会看到 Base64 的身影,例如 HTTP、JSON、JWT、邮件附件、图片上传等场景。

很多人第一次接触 Base64 时容易产生一个误解:

Base64 是一种加密算法吗?

实际上,Base64 不是加密,而是一种编码方式

它的核心作用是:将二进制数据转换成由有限字符组成的文本数据,从而方便在只适合传输文本的场景中传输二进制内容。

本文将从 Base64 的基本概念出发,详细介绍 Base64 的编码原理、解码过程、填充机制、数据膨胀问题,以及它在实际开发中的应用。

一、什么是 Base64?

Base64 是一种基于 64 个字符的二进制数据编码方式。

它可以将任意二进制数据转换成可打印的 ASCII 字符,例如:

text 复制代码
Hello

经过 Base64 编码后:

text 复制代码
SGVsbG8=

再进行 Base64 解码:

text 复制代码
SGVsbG8=
        ↓
Hello

因此,Base64 本质上是一个可逆的编码过程

text 复制代码
        Base64 编码
二进制数据 ─────────→ 文本字符串
    ↑                    │
    │                    │
    └──── Base64 解码 ────┘

需要特别强调:

Base64 不提供安全性,也不能用于保护敏感数据。

因为任何人都可以很容易地对 Base64 字符串进行解码。

例如:

text 复制代码
YWRtaW46MTIzNDU2

进行 Base64 解码后就是:

text 复制代码
admin:123456

所以,如果需要保护数据,应使用 AES、RSA 等加密算法,而不是 Base64。


二、为什么需要 Base64?

计算机中的数据本质上都是二进制:

text 复制代码
01001000 01100101 01101100 01101100 01101111

但是,在很多网络协议和数据格式中,更适合传输的是文本。

例如 JSON:

json 复制代码
{
    "name": "Tom"
}

如果直接把一段二进制数据放进 JSON,就可能出现:

text 复制代码
0x00
0xFF
0x1A
...

这些数据中可能包含不可打印字符或者特殊控制字符,不方便直接作为文本传输。

于是就可以使用 Base64:

text 复制代码
二进制数据
    ↓
Base64 编码
    ↓
ASCII 字符串
    ↓
JSON / HTTP / XML 等文本协议

例如图片可以转换成:

json 复制代码
{
    "image": "iVBORw0KGgoAAAANSUhEUg..."
}

这样,原本的二进制图片就变成了普通字符串。

因此,Base64 解决的核心问题可以概括为:

如何把任意二进制数据安全、统一地表示成文本字符。

这里的"安全"指的是传输格式上的安全和兼容性,而不是密码学意义上的安全。


三、Base64 为什么是 64 个字符?

Base64 使用 64 个字符来表示数据:

text 复制代码
A-Z
a-z
0-9
+
/

一共:

text 复制代码
26 + 26 + 10 + 1 + 1 = 64

为什么恰好是 64 个?

因为:

text 复制代码
2^6 = 64

也就是说:

6 个 bit 可以表示 64 种不同的值。

因此,一个 Base64 字符实际上对应:

text 复制代码
6 bit

例如:

text 复制代码
0     → A
1     → B
2     → C
...
25    → Z
26    → a
27    → b
...
51    → z
52    → 0
...
61    → 9
62    → +
63    → /

这就是 Base64 的核心字符映射表。


四、Base64 的核心编码原理

Base64 最核心的一句话就是:

每 3 个字节(24 bit)划分成 4 组,每组 6 bit,然后分别映射成一个 Base64 字符。

原始数据中:

text 复制代码
1 Byte = 8 bit

Base64 一个字符:

text 复制代码
1 字符 = 6 bit

因此:

text 复制代码
3 Byte
= 3 × 8 bit
= 24 bit

然后:

text 复制代码
24 bit
↓
4 × 6 bit
↓
4 个 Base64 字符

整个过程可以表示为:

text 复制代码
原始数据:

┌────────┬────────┬────────┐
│ 8 bit  │ 8 bit  │ 8 bit  │
└────────┴────────┴────────┘
           24 bit
              │
              ▼
┌──────┬──────┬──────┬──────┐
│ 6bit │ 6bit │ 6bit │ 6bit │
└──────┴──────┴──────┴──────┘
    │      │      │      │
    ▼      ▼      ▼      ▼
   0~63   0~63   0~63   0~63
    │      │      │      │
    ▼      ▼      ▼      ▼
   Base64 字符

这就是 Base64 最核心的工作机制。


五、通过 Hello 理解 Base64

下面通过 Man 这个字符串完整理解 Base64 的编码过程。

1. 获取 ASCII 编码

text 复制代码
M = 77
a = 97
n = 110

转换成二进制:

text 复制代码
M = 01001101
a = 01100001
n = 01101110

拼接:

text 复制代码
01001101 01100001 01101110

一共 24 bit。


2. 每 6 bit 进行分组

将 24 bit 按照 6 bit 重新划分:

text 复制代码
010011 010110 000101 101110

分别转换成十进制:

text 复制代码
010011 = 19
010110 = 22
000101 = 5
101110 = 46

3. 根据 Base64 字符表进行映射

根据 Base64 字符表:

text 复制代码
19 → T
22 → W
5  → F
46 → u

所以:

text 复制代码
Man
 ↓
TWFu

整个过程:

text 复制代码
Man
 ↓
01001101 01100001 01101110
 ↓
010011 010110 000101 101110
 ↓
19 22 5 46
 ↓
T W F u
 ↓
TWFu

这就是 Base64 编码。


六、Base64 为什么会出现 =

在实际使用中,经常可以看到这样的字符串:

text 复制代码
SGVsbG8=

最后的 = 是什么?

它叫做:

Padding(填充字符)

Base64 希望每次处理:

text 复制代码
3 Byte → 4 个字符

但是原始数据长度不一定刚好是 3 的倍数。

例如:

text 复制代码
Hello

一共有 5 个字节。

可以拆成:

text 复制代码
Hel + lo

其中:

text 复制代码
Hel = 3 Byte
lo  = 2 Byte

第一组可以正常转换。

第二组只有 2 Byte:

text 复制代码
16 bit

不足 24 bit,因此需要补 0,使其能够按照 6 bit 进行划分。

最终产生 3 个有效 Base64 字符,第四个位置使用:

text 复制代码
=

进行填充。

因此:

text 复制代码
Hello
↓
SGVsbG8=

七、Base64 的填充规则

Base64 的填充规则非常简单。

原始数据长度 Base64 结果
3 的整数倍 不需要 =
余 1 字节 最后增加 ==
余 2 字节 最后增加 =

例如:

text 复制代码
M
↓
TQ==
Ma
↓
TWE=
Man
↓
TWFu

可以总结为:

text 复制代码
原始数据长度 % 3

0 → 无填充
1 → ==
2 → =

需要注意的是,= 并不是实际的数据内容,而是用于表示数据长度和补齐编码结果。


八、Base64 为什么会增加数据量?

Base64 有一个非常明显的缺点:

编码后的数据会变大。

原因很简单。

原始数据:

text 复制代码
3 Byte = 24 bit

经过 Base64:

text 复制代码
4 个字符

如果按照一个字符 1 Byte 计算:

text 复制代码
4 Byte

所以:

text 复制代码
4 / 3 ≈ 1.333

也就是说:

Base64 编码后的数据理论上会增加约 33.3%。

例如:

text 复制代码
原始数据:300 MB
Base64:约 400 MB

实际数据由于填充等因素会有少量差异。

因此,对于大型二进制数据,例如:

  • 视频
  • 音频
  • 大型图片
  • 大文件

如果传输链路本身支持二进制数据,通常没有必要先转换成 Base64。

否则会造成:

text 复制代码
数据量增加
    ↓
网络带宽增加
    ↓
传输时间增加
    ↓
内存占用增加

九、Base64 编码和解码过程

Base64 编码:

text 复制代码
原始二进制
    │
    ▼
每 3 Byte 分组
    │
    ▼
24 bit
    │
    ▼
拆成 4 个 6 bit
    │
    ▼
转换成 0~63
    │
    ▼
查 Base64 字符表
    │
    ▼
Base64 字符串

Base64 解码则完全相反:

text 复制代码
Base64 字符串
    │
    ▼
查 Base64 字符表
    │
    ▼
得到 0~63
    │
    ▼
转换成 6 bit
    │
    ▼
4 × 6 bit = 24 bit
    │
    ▼
还原成 3 Byte
    │
    ▼
原始二进制数据

因此 Base64 是完全可逆的。


十、Base64 与 Hex 的区别

在开发过程中,Base64 和十六进制 Hex 都可以用于表示二进制数据。

例如:

text 复制代码
Hello

对应的 ASCII 十六进制:

text 复制代码
48 65 6C 6C 6F

Base64:

text 复制代码
SGVsbG8=

两者的主要区别:

对比项 Base64 Hex
使用字符数量 64 16
每个字符表示 6 bit 4 bit
数据膨胀 约 33% 约 100%
网络传输效率 较高 较低
可读性 一般 较好
二进制调试 一般 非常常见

所以可以简单理解:

Base64 更适合二进制数据的文本化传输。

而:

Hex 更适合查看、打印和调试二进制数据。


十一、Base64 在实际开发中的应用

1. HTTP

Base64 经常出现在 HTTP 场景中。

例如 HTTP Basic Authentication:

http 复制代码
Authorization: Basic YWRtaW46MTIzNDU2

其中:

text 复制代码
YWRtaW46MTIzNDU2

实际上就是:

text 复制代码
admin:123456

经过 Base64 编码后的结果。

但是 Base64 不具备加密能力,因此 Basic Authentication 通常需要配合 HTTPS 使用。


2. JSON

JSON 本身是文本格式,如果需要传递二进制数据,可以使用 Base64:

json 复制代码
{
    "data": "SGVsbG8="
}

服务端收到之后:

text 复制代码
SGVsbG8=
      ↓
Base64 Decode
      ↓
二进制数据

3. 图片

网页或者接口中经常可以看到:

text 复制代码
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...

这里的:

text 复制代码
iVBORw0KGgoAAAANSUhEUg...

就是图片经过 Base64 编码后的内容。


4. JWT

JWT 中也大量使用 Base64URL。

一个典型 JWT:

text 复制代码
xxxxx.yyyyy.zzzzz

实际上由三部分组成:

text 复制代码
Header.Payload.Signature

其中 Header 和 Payload 使用的是 Base64URL 编码

注意:

JWT 中的 Base64URL 也不是加密。

所以不要认为 JWT 的 Payload 因为经过 Base64URL 编码,就无法被别人看到。


十二、Base64URL 是什么?

标准 Base64 使用:

text 复制代码
+
/
=

但是 +/= 在 URL 中存在特殊含义,因此在 URL 场景中通常使用 Base64URL。

Base64URL 通常做以下转换:

text 复制代码
+ → -
/ → _

同时通常会去掉末尾的:

text 复制代码
=

例如:

text 复制代码
标准 Base64
TWFu+abc/xyz=

Base64URL:

text 复制代码
TWFu-abc_xyz

JWT 使用的就是这种变体。


十三、从程序员角度理解 Base64

如果从 C/C++ 开发的角度理解,可以把 Base64 看成两个函数:

cpp 复制代码
Base64Encode()
Base64Decode()

例如原始数据:

cpp 复制代码
uint8_t data[] = {
    0x48, 0x65, 0x6c, 0x6c, 0x6f
};

对应:

text 复制代码
48 65 6C 6C 6F

经过 Base64 编码:

text 复制代码
SGVsbG8=

再解码:

text 复制代码
SGVsbG8=
       ↓
48 65 6C 6C 6F

因此在网络程序中,如果看到一个 Base64 字符串,可以首先判断:

text 复制代码
Base64字符串
      ↓
Base64 Decode
      ↓
二进制数据
      ↓
根据实际协议继续解析

这一点在协议分析、网络抓包和流媒体开发中尤其重要。


十四、Base64 的优缺点

优点

1. 可以将二进制数据转换成文本

适合:

text 复制代码
HTTP
JSON
XML
邮件
配置文件

等文本场景。

2. 字符集简单

主要使用:

text 复制代码
A-Z
a-z
0-9
+
/
=

兼容性比较好。

3. 编码和解码简单

Base64 算法本身非常简单,CPU 开销通常较低。


缺点

1. 数据量增加

理论上增加约:

text 复制代码
33.3%

2. 不是加密

Base64 可以非常容易地被解码。

3. 不适合大型二进制数据的无意义转换

例如视频文件:

text 复制代码
原始视频
    ↓
Base64
    ↓
数据增加约 33%
    ↓
网络传输

如果网络协议本身支持二进制传输,就没有必要这么做。


十五、Base64 原理总结

Base64 的核心其实非常简单:

text 复制代码
          原始数据
             │
             ▼
       3 Byte = 24 bit
             │
             ▼
    ┌────┬────┬────┬────┐
    │6bit│6bit│6bit│6bit│
    └────┴────┴────┴────┘
       │    │    │    │
       ▼    ▼    ▼    ▼
      0~63 0~63 0~63 0~63
       │    │    │    │
       ▼    ▼    ▼    ▼
    Base64字符表
       │
       ▼
     文本字符串

可以记住下面几个关键点:

第一,Base64 是编码,不是加密。

第二,Base64 的核心是 3 字节转 4 字符。

第三,原始数据每 3 个字节会被拆成 4 组 6 bit。

第四,6 bit 可以表示 64 种状态,因此叫 Base64。

第五,数据长度不是 3 的倍数时,需要使用 = 进行填充。

第六,Base64 编码后数据量通常增加约 33%。

因此,一句话总结 Base64:

Base64 就是将二进制数据每 3 个字节组成 24 bit,再划分成 4 个 6 bit,并通过 64 个可打印字符进行映射,从而将二进制数据转换成文本字符串的一种编码方式。

相关推荐
0xBADCODE1 天前
CTF Writeup 合集
安全·web安全·网络安全·系统安全·密码学·php·ctf
Sagittarius_A*2 天前
协议与应用基础(三):HTTPS、证书链与中间人攻击
网络协议·http·信息安全·https·密码学·中间人攻击·证书链
黄金龙PLUS3 天前
ASCON置换算法的优缺点
算法·网络安全·密码学·哈希算法·同态加密
风行南方5 天前
后量子秘密:格密码入门(一)
密码学
网安蟹佬霸8 天前
# 网络流量分析实战:从Wireshark到入侵检测系统构建(2026最新版,附完整流量分析链与IDS规则集)
网络·测试工具·安全·开源·wireshark·密码学·哈希算法
小杨不想秃头9 天前
信息安全工程师教程第二章密码学
运维·服务器·密码学
汽车网络安全爱好者11 天前
AUTOSAR SecOC 深入解析(一):从 Freshness Value 到 MAC 认证的完整流
物联网·网络安全·汽车·密码学
小网洞12 天前
免费WPA无线握手包在线分析跑包网站
网络·网络安全·密码学·wps
网安蟹佬霸14 天前
密码学安全实战:从加密原理到哈希破解的完整攻防指南
网络·算法·安全·web安全·开源·密码学·哈希算法