Base64是什么编码?和加密的区别、结尾的等号、中文乱码全说清

邮件附件、网页里的小图标、JWT 令牌、接口报文……到处能见到一长串以 == 结尾的字母数字——那就是 Base64。它经常被叫成"Base64 加密",但要先纠正一个最关键的误区:Base64 是编码,不是加密,它没有密钥、算法公开,任何人拿到都能立刻还原。它的真正用途,是让二进制数据能安全地"坐车"穿过只认文本的通道。

Base64 的原理:3 个字节变 4 个字符

网络传输的文本通道只保证 64 个"安全字符"不出问题。Base64 的做法是:把原始数据每 3 个字节(24 位)切成 4 组、每组 6 位,再用 64 个字符(A-Z a-z 0-9 + /)把这 6 位数翻译成一个可打印字符。

  • 3 字节 → 4 字符,所以体积膨胀约 33%;
  • 原文长度不是 3 的倍数时,用 = 号补位占位:余 1 字节补两个 =,余 2 字节补一个 =;
  • 这就是"Base64 结尾常有等号"的原因——等号是长度对齐标记,不是内容。

它用在哪里?

  • 邮件附件:最老的用途,SMTP 邮件协议最初只支持纯文本;
  • 网页内嵌小图:<img src="data:image/png;base64,...>,少一次请求,代价是体积+33% 且无法单独缓存,只适合小图标;
  • HTTP Basic 认证、JWT 令牌:把用户名密码、令牌载荷变成文本安全传输;
  • JSON/配置文件里携带二进制:如证书、公钥、验证码图片。

URL-Safe 变体:JWT 里为什么没有 + 和 / ?

+、/、= 在 URL 里有特殊含义,直接放进链接会被转义或截断。于是有了 URL-Safe Base64:+ 换成 -,/ 换成 _,并去掉补位等号。JWT 的三段式令牌用的就是它——所以拿标准 Base64 工具解 JWT 时,要先切到 URL-Safe 模式。

中文乱码的根源:编码时和解码时字符集不一致

Base64 操作的是字节,而"中文"要先变成字节才有 Base64。同一句"你好",UTF-8 和 GBK 得到的字节不同,Base64 自然不同;用 UTF-8 编码、却按 GBK 解码(或反过来),就会得到乱码。规矩只有一条:编码解码都用 UTF-8。另一个常见原因是复制时漏了末尾等号或中间字符,解码直接报错。

场景该用 Base64 吗说明
邮件附件、JWT、接口传二进制✅ 正是它的本职通道只认文本时它是标准解法
给数据"保密"❌ 完全不行无密钥、可逆,等同于明文
压缩体积❌ 反而变大膨胀约 33%,需要压缩用 gzip/zip
需要验证是否被篡改❌ 用错工具应该用哈希,见 MD5/SHA 一文
Base64 编解码 文本与 Base64 互转,UTF-8 中文不乱码,支持 URL-Safe 模式,浏览器本地完成
在线编码解码 Base64

需要把图片变成 DataURL 内嵌进网页,可以用图片转 Base64 工具,本地转换不上传。处理 JSON 时遇到转义问题,则看这篇 JSON 格式入门。

常见问题(FAQ)

Base64是加密吗?

不是。Base64 只是"编码":把任意字节换一种写法表示,算法公开、没有密钥,任何人拿到都能立刻解码,起不到保密作用。它的目的是让二进制数据能安全地通过只支持文本的通道(邮件、JSON、URL),而不是保护数据。

Base64结尾为什么常有一两个等号(=)?

Base64 把每 3 个字节重排成 4 个字符。原文长度不是 3 的倍数时,末尾缺几位就用几个 = 补齐占位:余 1 个字节补两个 =,余 2 个字节补一个 =,整除时没有等号。等号是长度对齐标记,解码时会去掉。

为什么中文Base64解码后是乱码?

多半是字符集不一致:编码时按 UTF-8 处理、解码后却按 GBK 解释(或反过来)。中文 Base64 一定要"编码解码都用 UTF-8";另一个常见原因是复制时截断了末尾的等号或中间字符。

JWT 为什么把 Base64 里的 + 和 / 换成了 - 和 _?

因为 + / = 在 URL 里有特殊含义,放进链接会被转义出错。JWT 使用 URL-Safe 变体:+ 换成 -、/ 换成 _、并去掉补位的 =。给 Base64 工具切换到"URL-Safe"模式即可处理这类内容。

网页里内嵌 <img src="data:image/png;base64,..."> 有什么优缺点?

优点:图片不再发额外请求,小图标可随 HTML/CSS 一次加载完;缺点:Base64 让体积膨胀约 33%,且无法被浏览器单独缓存。适合几十 KB 以内的小图,大图仍应使用独立文件。