上个月联调接口,后端返回一段以 = 结尾的长字符串,前端同事说"这是 Base64,解码看看"。我第一次见这玩意儿,还以为是加密,问了句"怎么解密",被笑了半天。后来才发现 Base64 是程序员最常用的老朋友:邮件附件、图片内嵌、接口传参,到处都有它。

Base64 是什么,先记住一句话

Base64 是把二进制数据用 64 个可打印字符表示的编码方式。它不改变数据的含义,只是换一种"写法"——所以它不是加密。加密需要密钥,Base64 谁都能解开。

为什么偏偏是 64 个字符

2 的 6 次方等于 64,所以 6 位二进制正好对应 64 种组合。Base64 用大小写字母(52 个)、数字(10 个)、加号和斜杠凑齐 64 个字符,再把二进制数据每 6 位一组映射成可见字符,末尾用 = 做填充。

Base64 编码过程示意图:Man 经过二进制和 6 位分组得到 TWFu
图:Man 三个字符 → 24 位二进制 → 4 个 6 位组 → 查表得到 TWFu,整个过程只是“换写法”,不改变数据含义

为什么末尾总有 =

Base64 每 4 个字符表示 3 个字节。如果原始数据长度不是 3 的倍数,最后就用 = 补齐到 4 的倍数。所以看到结尾一个或两个 = 是正常现象,说明原始数据长度刚好不是 3 的倍数,不是出错了。

Base64 都用在哪

图片内嵌:把图片转成 data URI 直接写进 HTML 或 CSS,减少请求数,用图片转Base64可以一键生成。邮件附件:早期邮件协议只能传文本,附件先编码成 Base64 再发。接口传参:二进制数据不好直接放 URL 或 JSON,先编码成安全字符串再传。配置存储:把二进制内容以文本形式存进数据库或配置文件。

URL 场景要用 URL Safe 变体

标准 Base64 的字符表里有 + 和 /,这两个字符在 URL 里会被特殊处理(+ 可能被当成空格,/ 会干扰路径),所以 URL 场景一般用 URL Safe 变体:把 + 换成 -、/ 换成 _,结尾的 = 也常常去掉。站里的Base64编解码工具提供了 URL 安全模式选项,遇到这类需求直接勾选即可。

和十六进制是一回事吗

不是。Hex 把每个字节拆成两个十六进制字符,体积膨胀一倍;Base64 每 3 个字节用 4 个字符,膨胀约 1/3,更紧凑。Hex 适合人读、方便对齐查看,Base64 适合机器间传输,各有用处。

直接动手试试

打开Base64编解码工具,输入任意文本(中文也支持)立刻看到编码结果;把一串 Base64 粘进去就能解码。想试图片版,用图片转Base64拖一张图进去就出 data URI。

常见几个问题:Base64 是加密吗?不是,别把密码、密钥这类敏感信息用 Base64 传输,那等于明文。为什么体积变大?每 3 个字节变成 4 个字符,大约膨胀 33%,这是它换来的"能在纯文本环境安全传输"的代价。中文会乱码吗?中文是多字节字符(UTF-8 下汉字占 3 字节),直接编码没问题,解码时记得用 UTF-8。站里的工具已经处理了这个细节。

再分享一个我踩过的坑:把 Base64 拼进 data URI 时,如果字符串里有换行符,某些浏览器会解析失败,所以生成后要确保是连续的一行。还有跨语言传输时,不同库对末尾 = 填充和 URL Safe 的处理不一样,Java 和 Python 的 Base64 库默认行为就有差异,联调前先确认两边用的是不是同一套变体,能省不少来回折腾的时间。

Base64 不难,难的是第一次建立起"编码不是加密"的直觉。花两分钟用工具玩一次,下次再看到 = 结尾的字符串,你就知道它是什么了。