什么是 Base64 编码?开发者的可视化指南
Source: Dev.to
什么是 Base64 编码?开发者的可视化指南
Base64 是一种 二进制到文本 的编码方案,常用于在只能处理文本的系统(如 JSON、XML、URL、电子邮件)中安全地传输二进制数据。它通过把每 3 个字节(24 位)转换为 4 个可打印字符(每个字符 6 位),从而避免了控制字符和不可见字符带来的问题。
为什么需要 Base64?
- 网络传输:某些协议只接受 ASCII 文本(例如 HTTP 表单、URL 参数)。
- 数据嵌入:在 HTML、CSS、JSON 中直接嵌入图片或其他二进制资源。
- 兼容性:确保二进制数据在不同平台、语言之间保持一致。
注意:Base64 并不是加密,它只是编码。任何人都可以轻易地把 Base64 解码回原始二进制。
Base64 的工作原理(可视化)
原始字节: 01001000 01100101 01101100 (ASCII "Hel")
分组: 010010 000110 010101 101100
映射: 18 6 21 44
字符: S G V s
结果: "SGVs"
- 把输入数据分成 3‑byte(24 位)块。
- 每块再划分为 4‑group(6 位)。
- 使用 Base64 索引表(A‑Z, a‑z, 0‑9,
+,/)把每个 6 位值映射为对应的字符。 - 如果最后不足 3 字节,使用
=填充,使输出长度始终是 4 的倍数。
常见的 Base64 索引表
| 十进制 | 字符 | 十进制 | 字符 |
|---|---|---|---|
| 0‑25 | A‑Z | 26‑51 | a‑z |
| 52‑61 | 0‑9 | 62 | + |
| 63 | / |
URL‑安全的变体把
+替换为-,/替换为_,并且通常省略填充=。
示例代码
下面的代码展示了在 JavaScript 与 Python 中如何进行 Base64 编码和解码。代码块保持原样,不进行翻译。
// JavaScript (Node.js)
const data = "Hello, World!";
const encoded = Buffer.from(data).toString('base64');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
console.log(decoded); // Hello, World!
# Python 3
import base64
data = b"Hello, World!"
encoded = base64.b64encode(data).decode('utf-8')
print(encoded) # SGVsbG8sIFdvcmxkIQ==
decoded = base64.b64decode(encoded).decode('utf-8')
print(decoded) # Hello, World!
何时使用 Base64?
| 场景 | 说明 |
|---|---|
嵌入小型图像(如在 HTML <img src="data:image/png;base64,...">) | 省去额外的 HTTP 请求 |
| 在 JSON / XML 中传递二进制 | 保持文本格式的完整性 |
| 在 URL 参数中传递二进制(使用 URL‑安全 Base64) | 避免特殊字符冲突 |
| 在电子邮件(MIME)中发送附件 | 符合 RFC 2045 标准 |
何时避免使用 Base64?
- 大文件:Base64 会使数据体积增加约 33%,不适合传输大文件(如视频、完整图片库)。
- 需要加密:如果目的是保护数据隐私,请使用加密算法(AES、RSA 等),而不是仅仅 Base64。
- 性能敏感的场景:编码/解码会消耗 CPU,频繁的转换可能成为瓶颈。
小结
- Base64 是一种 二进制 → 文本 的编码方式,广泛用于在只能处理文本的环境中安全传输二进制数据。
- 它通过 3 字节 → 4 字符 的映射实现,使用固定的 64‑字符索引表。
- 虽然易于实现且兼容性好,但会导致 数据膨胀,并且 不提供安全性。
- 正确的使用场景包括嵌入小型资源、在 JSON/XML 中携带二进制、以及电子邮件附件等;不适用于大文件或需要保密的场景。
了解更多细节,请参考 RFC 4648(Base64 标准)以及各语言的标准库实现。祝编码愉快!
什么是 Base64?
Base64 是一种二进制转文本的编码方案。它可以将任何二进制数据 — 图像、文件、文本,等等 — 使用仅 64 个“安全” ASCII 字符来表示:
A‑Z (26) + a‑z (26) + 0‑9 (10) + '+' + '/' = 64 characters
再加上用于填充的 =。
就是这么简单。整个字符表的设计旨在能够安全地通过仅处理文本的系统进行传输 — 电子邮件、URL、JSON、XML、HTML。
为什么会有 Base64?
在早期的互联网时代,许多系统只能处理 7 位 ASCII 文本。二进制数据(图像、可执行文件、非英文字符)在通过电子邮件服务器、网关以及为纯文本设计的协议传输时会被损坏。
Base64 通过将二进制数据编码为文本安全的格式来解决了这个问题。
权衡是什么? 编码后的输出大约比原始数据 大 33 %。
计算方法: 每 3 字节的输入会变成 4 个 Base64 字符
3 × 8 = 24 bits → 4 × 6 = 24 bits
Base64 编码工作原理(逐步说明)
让我们将字符串 "Hi" 编码为 Base64。
步骤 1:转换为二进制
H = 72 → 01001000
i = 105 → 01101001
步骤 2:连接所有位
01001000 01101001
步骤 3:划分为 6 位一组
010010 | 000110 | 1001XX
(将最后一组用零填充至 6 位:100100)
步骤 4:将每个 6 位组映射到 Base64 字母表
010010 = 18 → S
000110 = 6 → G
100100 = 36 → k
步骤 5:添加填充
由于我们的输入是 2 个字节(不能被 3 整除),我们需要添加一个 = 填充。
结果: SGk=
您可以自行验证 →
在实际场景中看到 Base64 的位置
-
Data URIs – 在 HTML/CSS 中直接嵌入小图片,省去额外的 HTTP 请求。
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."> -
JWT Tokens – 三个 Base64url 编码的 JSON 对象通过点号连接。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U -
Email Attachments (MIME) – 每个附件都使用 Base64 编码,以便在基于文本的电子邮件中嵌入二进制文件。
-
API Responses – 二进制数据(PDF、图片、证书等)常以 Base64 字符串的形式在 JSON 中返回。
{ "file": "UGFzc3dvcmQxMjM=", "encoding": "base64" } -
Basic HTTP Authentication – 对
username:password进行编码。Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Base64 并非加密
最常见的误解是 Base64 提供安全性。它是 编码,而不是 加密。
| 编码 | 加密 |
|---|---|
| 将数据转换为不同的格式(任何人都可以逆向) | 使用密钥保护数据(只有持有密钥才能逆向) |
Base64 提供 零 安全性。任何人都可以立即解码。绝不要用它来“隐藏”敏感数据。
# "Hiding" a password in Base64
echo -n 'MySecretPassword' | base64
# TXlTZWNyZXRQYXNzd29yZA==
# "Unhiding" it
echo 'TXlTZWNyZXRQYXNzd29yZA==' | base64 -d
# MySecretPassword
Base64 与 Base64url
标准 Base64 使用 + 和 /,在 URL 中会导致问题。Base64url 用以下方式替换它们:
| 标准 | URL 安全 |
|---|---|
+ | - |
/ | _ |
=(填充) | 通常省略 |
JWT 令牌使用 Base64url,许多在查询参数中放置编码数据的 API 也使用它。
常用 Base64 操作
JavaScript(浏览器)
// Encode
const encoded = btoa('Hello, World!'); // SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = atob('SGVsbG8sIFdvcmxkIQ=='); // Hello, World!
⚠️
btoa()和atob()只能处理 ASCII。若需 Unicode:
// Encode Unicode
const encoded = btoa(unescape(encodeURIComponent('Hello 🌍')));
// Decode Unicode
const decoded = decodeURIComponent(escape(atob(encoded)));
Node.js
// Encode
const encoded = Buffer.from('Hello').toString('base64');
// Decode
const decoded = Buffer.from('SGVsbG8=', 'base64').toString('utf8');
Python
import base64
# Encode
b64 = base64.b64encode(b'Hello').decode()
# 'SGVsbG8='
# Decode
txt = base64.b64decode('SGVsbG8=').decode()
# 'Hello'
命令行
# Encode a string
echo -n 'Hello' | base64
# Decode a string
echo 'SGVsbG8=' | base64 -d
# Encode a file
base64 image.png > image.b64
# Decode a file
base64 -d image.b64 > image.png
何时使用 Base64
✅ 适用场景:
- 在基于文本的格式(JSON、XML、HTML)中嵌入二进制数据
- 通过仅文本协议发送文件
- 为小图片(< 10 KB)创建 data URI
- 与期望 Base64 输入的 API 配合使用
❌ 不适用场景:
- 认为它能提供安全性(其实并不能)
- 文件较大(33 % 的大小开销会累计)
- 可以直接发送原始二进制数据(例如通过 multipart/form‑data)
- 试图压缩数据(它只会让数据更大)
亲自尝试
我在 base64decode.co 上构建了一个免费 Base64 编码/解码工具——粘贴任意文本或上传文件,即可即时得到结果。无需注册,无追踪,完全在浏览器中运行。
这是我为日常开发工作构建的 11 个免费开发者工具 套件的一部分。
你最常用 Base64 的场景是什么? 在评论中告诉我——我很好奇是用于 JWT、data URI,还是我未曾想到的其他用途。