使用方法
- 把要检查的字符串粘贴到输入框中。
- 查看结论:是否有效、识别出的变体(标准或 URL 安全)以及解码后的大小。
- 如果列出了问题,根据给出的位置找到无效字符、空白字符或位置不对的填充。
- 查看识别出的内容类型,判断数据是文本还是 PNG、PDF、ZIP 等文件。
什么样的 Base64 才有效
- 字母表。只能包含
A-Z、a-z、0-9以及另外两个字符:标准 Base64 是+和/,Base64URL 是-和_。如果一个字符串同时出现了这两组字符,通常是数据已损坏,或者由两段不同来源的内容拼接而成。 - 填充。
=只能出现在末尾,且最多两个。填充出现在中间,通常说明两段编码结果被直接拼在了一起。 - 长度。带填充时,长度必须是 4 的整数倍。不带填充时,除了 4n + 1 以外的长度都可以:单独剩下的一个字符只有 6 位,凑不成一个字节。
严格的解码器还有一条规则:最后一个字符中未使用的低位必须为 0。很多解码器会忽略这些位,但也有一些会直接拒绝,例如 Go 的 base64.StdEncoding.Strict()。
常见错误及解决方法
| 问题 | 常见原因 | 解决方法 |
|---|---|---|
| 无效字符 | 复制时连带了引号、反斜杠,或 %2B、%3D 等转义 | 删除多余字符,或先做 URL 解码 |
| 中间有空格 | 经过 URL 或表单传递时 + 被转成了空格 | 把 + 改回来,在 URL 中改用 Base64URL |
| 长度为 4n + 1 | 被列宽限制、日志截断或只复制了一部分 | 重新复制完整的值 |
| 填充在中间 | 两段 Base64 被拼接在一起 | 拆开后分别解码 |
| 含有换行 | MIME 或 PEM 格式的折行 | 一般无害;需要单行时删除换行 |
有效不等于有意义
Base64 既没有文件头也没有校验和,所谓有效只说明这个字符串可以被解码。很多普通单词都能通过校验,因为任意 4 个字母都能组成合法的一组。所以校验工具还会实际解码数据,并报告大小和内容类型。如果解码出可读文本,或者能识别出 PNG、PDF、ZIP 等文件签名,就基本可以确定它确实是 Base64;如果只得到几个随机字节,则不然。想同时尝试其他编码,可以使用 编码识别 工具。
在代码中校验 Base64
// JavaScript:带填充的标准 Base64(空字符串也会匹配)
/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/
# Python:遇到无效字符时报错,而不是跳过
import base64, binascii
try:
base64.b64decode(s, validate=True)
except binascii.Error:
print('invalid')
常见问题
为什么普通单词也被判定为有效 Base64?
因为它确实有效。只要由字母表中的字符组成且长度合适,就能解码出一些字节,例如单词
test 会解码成 3 个字节。请查看识别出的内容类型:如果结果既不是可读文本,也不是已知的文件类型,那么输入很可能本来就不是 Base64。带空格或换行的 Base64 有效吗?
MIME 和 PEM 会把 Base64 折成多行,大多数解码器也会跳过空白字符。但 JSON 字段、HTTP 头、JWT 和 Data URI 都要求是一个连续的字符串。校验工具会单独列出空白字符,方便你根据实际用途判断是否需要处理。
没有 = 填充的 Base64 有效吗?
通常有效。Base64URL 一般不带填充,RFC 4648 也允许在长度可由上下文确定时省略填充。不过有些严格的解码器仍然要求填充,如果被拒绝,可以补上
= 使长度为 4 的整数倍。长度为 4n + 1 的无填充字符串永远无效。在 JavaScript 中如何判断字符串是不是 Base64?
如果要严格校验带填充的 Base64,可以用正则表达式匹配“若干组 4 个字母表字符,末尾可带填充”的格式;更简便的做法是把
atob() 放在 try/catch 中调用。注意,atob() 遇到无效输入会抛出 InvalidCharacterError,但会默默接受空白字符和缺失的填充,而且不接受 URL 安全字符。