Base64 编解码完整详解
一、什么是 Base64
Base64 是二进制 → 文本的编码方式(不是加密!),把任意二进制字节(图片、文件、二进制数据)转换成由64个可打印ASCII字符组成的字符串,方便在只支持文本传输的协议里传递二进制数据。
核心用途:URL、Cookie、邮件MIME、JSON里嵌入图片、接口传二进制;不能用来加密,任何人拿到字符串都可以还原原始数据。
Base64 字符表(共64个)
索引 0~25:A-Z
索引26~51:a-z
索引52~61:0-9
索引62:+
索引63:/
填充符:=(不属于64个编码字符,只做补齐)
变体:Base64URL,把
+→-,/→_,去掉末尾=,用于URL参数。
二、编码原理
Base64 以3字节(24bit)为一组,拆分成为 4个6bit 的小块;
每个6bit的取值范围 0~63,正好对应上面64个字符表。
- 原始:3字节 = 8bit ×3 = 24 bit
- 切分:24bit ÷ 6 = 4段6bit
- 每段6bit的值查表,得到4个Base64字符
补齐规则(重点)
原始字节长度不是3的倍数时,末尾补0比特,并用 = 标记填充了多少字节:
- 剩余 1字节(8bit):补4个0bit → 2个Base64字符,末尾2个等号
== - 剩余 2字节(16bit):补2个0bit → 3个Base64字符,末尾1个等号
= - 刚好3字节整数倍:无
=
=只允许出现在字符串末尾,中间不能出现。
编码示例
原始文本:Man
- M: 0x4D (01001101)
- a: 0x61 (01100001)
- n: 0x6E (01101110)
拼接比特流:01001101 01100001 01101110
按6bit切割:010011 010110 000101 101110
对应十进制:19, 22, 5, 46 → 查表:T W F u
Man → Base64:TWFu
再举单字节例子:A(0x41,01000001)
比特:01000001,补4个0 → 010000 010000
得到2个字符,后面补== → QQ==
三、解码原理
解码是编码逆过程:
- 去掉末尾填充符
= - 每个Base64字符查表得到6bit数值
- 拼接所有6bit二进制串
- 按8bit一组切分,还原原始字节
- 丢弃补的多余0比特
校验:Base64字符串长度一定是4的倍数;非法字符、长度不对会解码失败。
四、编码后体积变化
原始每3字节 → 输出4个字符
压缩比例:4/3 ≈ 1.33倍
✅ Base64编码后,数据体积变大33%。
例:100KB图片,Base64之后大约133KB。
五、常见Base64变体
| 类型 | 字符替换 | 填充 | 使用场景 |
|---|---|---|---|
| Standard Base64 | + / | 末尾 = | MIME邮件 |
| Base64URL | +→- /→_ | 去掉= | URL、JWT |
| Base64 MIME | 标准,自动换行 | = | 邮件附件 |
JWT 就是 Base64URL 编码,所以没有末尾
=。
六、常用工具代码示例
Python 编解码
import base64
# 编码:字符串 -> bytes -> base64 bytes -> str
s = "hello 世界"
b = s.encode("utf-8")
b64 = base64.b64encode(b).decode("utf-8")
print(b64)
# 解码
raw = base64.b64decode(b64).decode("utf-8")
print(raw)
# Base64URL
b64url = base64.urlsafe_b64encode(b).rstrip(b'=').decode()
print(b64url)
JavaScript 浏览器端
// 编码(注意:btoa只支持ASCII,中文要先转UTF8)
function toBase64(str){
return btoa(unescape(encodeURIComponent(str)));
}
// 解码
function fromBase64(b64){
return decodeURIComponent(escape(atob(b64)));
}Linux shell
# 编码
echo -n "test" | base64
# 解码
echo "dGVzdA==" | base64 -d
七、常见误区
- ❌ Base64是加密:不是加密,只是编码,明文可逆,不能用来存密码。
- ❌ Base64可以压缩数据:反而增大33%体积。
- ❌ Base64字符串可以随便换行:标准MIME允许76字符换行;URL场景不能换行。
- ❌ Base64一定带
=:Base64URL会把填充等号删掉。 - ❌ 图片base64直接存数据库万能:体积大,查询慢,适合小图标,大图不推荐。
八、典型应用场景
- HTML/CSS:内嵌小图片
data:image/png;base64,xxxx,减少HTTP请求 - JWT令牌:header、payload 使用Base64URL编码
- 邮件MIME:早期SMTP只支持文本,二进制附件Base64传输
- HTTP接口:二进制内容放到JSON字符串传递
- 证书、密钥文本化展示
九、简单自测
原始:ABC
编码结果:QUJDA==
如果你需要,我可以:
- 写一个极简手写Base64编解码实现(C/Python),不调用内置库,方便理解底层;
- 或者给你一个在线可直接用的Base64编解码小工具代码。