Base64:用 33% 的体积膨胀,买一张在文本世界通行的门票

如果你见过 JWT 里那一长串 eyJhbGciOiJIUzI1NiIs...,或者在 JSON 里塞过图片的字符串,或者在 PEM 证书里复制过 BEGIN PUBLIC KEY 下面那堆乱码------你已经和 Base64 打过无数次交道了。但很多人只是"会用",并不理解它到底在做什么,以及为什么明明会让数据变大,我们却离不开它。

这篇文章把 Base64 的编码原理和工程逻辑彻底讲清楚。


一、Base64 到底在解决什么问题?

计算机世界里有两套"语言体系":

  • 二进制世界 :图片、音频、加密后的密文、protobuf 消息......它们是任意的 0 和 1,可能包含 \0、<、>、&、控制字符等"危险分子"。
  • 文本世界 :JSON、XML、HTML、URL、邮件协议、配置文件......它们只认可打印的 ASCII 字符,看到 \0 就截断,看到 < 以为是标签开头,看到 & 以为是转义符。

Base64 是一座桥:它把二进制数据翻译成文本世界能安全识别的字符,让二进制数据能在邮件里发、在 JSON 里传、在 URL 里带、在配置文件里存。

代价是体积膨胀约 33% (3 字节二进制变成 4 字节 ASCII)。但工程上,兼容性往往比带宽更贵。


二、编码原理:6 位一组的"切片游戏"

为什么是 6 位?

ASCII 有 128 个字符,但安全、无歧义、可打印的只有 64 个:

  • 大写 A-Z(26 个)
  • 小写 a-z(26 个)
  • 数字 0-9(10 个)
  • 符号 + 和 /(2 个)

2⁶ = 64,所以 6 位二进制正好能映射到一个安全字符。

核心过程:3 字节 → 4 字符

以经典的 "Man" 为例:

第一步:转成二进制

字符 ASCII 码 二进制
M 77 01001101
a 97 01100001
n 110 01101110

拼接成 24 位:01001101 01100001 01101110

第二步:按 6 位重新切分

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

第三步:查 Base64 索引表

索引 字符
0-25 A-Z
26-51 a-z
52-61 0-9
62 +
63 /
r 复制代码
19 → T,  22 → W,  5 → F,  46 → u

结果 :"Man" → "TWFu"


三、补零与补等号:不足 3 字节怎么办?

Base64 的基本单位是 24 位(3 字节 × 8 位 = 4 组 × 6 位)。如果原始数据不是 3 的倍数,就在末尾补 0,凑成 24 位,输出后再用 = 标记补了多少。

原始字节数 补齐后 输出字符数 结尾
3 无需补齐 4 无
2 补 8 个 0 → 24 位 3 =
1 补 16 个 0 → 24 位 2 ==

示例:"M"(只有 1 字节)

ini 复制代码
M = 01001101
补齐:01001101 00000000 00000000
切分:010011 | 010000 | 000000 | 000000
索引:19     | 16     | 0      | 0
字符:T      | Q      | =      | =

结果:"M" → "TQ=="

那个 = 不是数据的一部分,只是填充标记,解码时会丢弃。


四、为什么体积大了 33%,我们还离不开它?

Base64 不是"最优解",而是**"工程上最可靠的兼容解"**。以下场景它几乎是标准答案:

1. Data URI:把资源直接嵌进代码

html 复制代码
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

一张 1KB 的小图标,Base64 后变成 1.33KB,但省掉了一次 HTTP 请求。对首屏关键资源来说,零延迟比 300 字节体积重要得多。

2. JWT:在 HTTP Header 里传"自包含令牌"

text 复制代码
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMe...

JWT 的 Header 和 Payload 本质是 JSON,但必须放在 HTTP Header 这种纯文本环境 里。Base64URL(把 + 换成 -,/ 换成 _)是 JWT 的标准编码方式。

3. 证书与密钥:PEM 格式

text 复制代码
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----

DER 二进制证书被 Base64 包裹后,可以安全地复制粘贴到聊天框、邮件、GitHub Issue、配置文件里,不会因为字符集转换而损坏。

4. JSON 里的二进制字段

前后端交互时,图片、文件、加密数据往往这样传:

json 复制代码
{
    "filename": "avatar.png",
    "content": "iVBORw0KGgoAAAANSUhEUgAAADIA..."
}

虽然直接传二进制更高效,但整个 JSON.stringify + json.Unmarshal 生态都是文本的。Base64 是最省事的兼容方案。

5. 邮件附件:MIME 标准

早期邮件网关只支持 7-bit ASCII,MIME 标准强制用 Base64 编码附件。这个历史包袱至今仍在------你发邮件带 PDF,底层还是 Base64。


五、什么时候不该用 Base64?

场景 替代方案 原因
微服务内部 RPC Protobuf / gRPC 二进制直接传,零膨胀,解析快 10 倍
大文件传输(>10MB) 分片二进制流 33% 膨胀是实打实的带宽和存储成本
高频低延迟交易 固定二进制协议 编码解码耗时不可接受
对象存储(S3/OSS) 直接上传二进制 存储按量计费,Base64 不划算

原则:如果通信双方都能处理裸二进制,就不要用 Base64 给自己加戏。


六、Go 实战:标准库零值可用

Go 的 encoding/base64 包设计非常简洁,零值可用:

go 复制代码
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	data := []byte("Man")

	// 标准编码
	encoded := base64.StdEncoding.EncodeToString(data)
	fmt.Println(encoded) // TWFu

	// 解码
	decoded, _ := base64.StdEncoding.DecodeString(encoded)
	fmt.Println(string(decoded)) // Man

	// URL 安全编码(JWT 专用)
	urlSafe := base64.URLEncoding.EncodeToString([]byte("hello+world/test"))
	fmt.Println(urlSafe) // aGVsbG8rd29ybGQvdGVzdA==
}

两个编码器的区别:

标准 URL 安全
+ + -
/ / _
padding = 可选去掉

JWT 用的是 base64.URLEncoding,因为标准 Base64 的 + 和 / 在 URL 里会被转义成 %2B 和 %2F,体积反而更大。


七、总结

Base64 的本质不是压缩,也不是加密,而是编码------它用一种文本世界能读懂的字母表,复述了一遍二进制数据的内容。

  • 原理 :3 字节拆成 4 个 6 位组,每组查表变成一个 ASCII 字符,不足补 =。
  • 代价:体积膨胀 33%。
  • 收益 :二进制数据能在 JSON、URL、邮件、HTML、配置文件里无损、无歧义地通行。
  • 原则:对外兼容用 Base64,对内性能用二进制。

你在工作中遇到过哪些 Base64 的诡异 bug?比如忘了用 URL 安全版本导致 JWT 解析失败,或者把 Base64 当加密算法用?欢迎在评论区分享。


相关推荐
Java爱好狂.5 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
马良神笔7 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD7 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机7 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机7 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒9 小时前
数组、切片和Map
后端
专注仿真9 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷9 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m555555559 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
易小尊9 小时前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端