如何解码 Base64
- 把 Base64 粘贴到 输入 · Base64 框中。换行、空格、两侧的引号和
data:...;base64,前缀都可以保留,解码器会自动去掉它们。 - 解码后的文本显示在 输出 · 文本 中。状态行会显示 有效的 Base64、变体(标准或 Base64URL)、解码后的字节数,以及 看起来像 一栏中检测到的内容类型。
- 如果文本是乱码,请更换 字符集,或选择 自动检测。
- 如果内容是 JSON,格式化 JSON 会将其缩进,方便阅读。
- 点击 复制输出,或点击 下载 把解码后的字节保存为文件。扩展名取决于检测到的类型,所以 JSON 会保存为
decoded.json,PNG 会保存为decoded.png。
互换 会把解码后的文本送回输入框并切换为编码模式,可以快速确认字符串能否原样往返转换。
解码器接受哪些输入
Base64 很少是干干净净送到你手上的。它可能来自邮件、按 76 个字符换行,可能来自 JSON 文件、带着引号,可能来自 URL、经过了百分号编码,也可能来自令牌、没有填充。解码器无需任何设置就能接受这些输入:
| 你粘贴的 | 你得到的 | 发生了什么 |
|---|---|---|
SGVsbG8gV29ybGQ | Hello World | 补全了缺失的 =,状态行会说明 |
8J-Riw | 👋 | 识别出 URL 安全的 - 和 _,变体显示为 Base64URL |
data:text/plain;base64,SGk= | Hi | 去掉了 data URI 前缀 |
"SGVsbG8=" | Hello | 去掉了来自代码或 JSON 的引号 |
SGVsbG8%3D | Hello | 把 URL 编码的 %3D 读作 = |
SGVs(换行)bG8= | Hello | 跳过了换行和空格 |
解码器对这些外包装很宽容,对其他一切都很严格:遇到字母表以外的字符时,它会停下并报错,指出该字符及其位置。有些库则会悄悄跳过坏字符,交给你一个已损坏的输出(见下面的代码部分)。
专门处理 URL 安全令牌的 Base64URL 解码器 讲解了这种字母表,Base64 与 Base64URL 的区别 则介绍了两者的差异。
解码结果是文件时
Base64 可以承载任何字节,很多 Base64 字符串其实是图片或文档。工具会把解码后数据的开头字节与已知的文件签名(magic number)进行比对,并把结果显示在 看起来像 中:PNG、JPEG、PDF、ZIP、gzip、JSON、XML 等等。对于二进制格式,它会显示可打印字符的预览,提示这是二进制数据,并给出对应工具的链接,例如 Base64 转图片 或 Base64 转 PDF。无论哪种情况,下载 都会保存原始字节。
Base64 字符串的开头,往往在解码之前就暴露了格式:
| Base64 开头 | 解码后的字节 | 格式 |
|---|---|---|
iVBORw0KGgo | 89 50 4E 47 0D 0A 1A 0A | PNG 图片 |
/9j/ | FF D8 FF | JPEG 图片 |
JVBERi0 | %PDF- | PDF 文档 |
UEsDBA | PK 03 04 | ZIP,以及 DOCX 和 XLSX |
H4sI | 1F 8B 08 | gzip 数据(gzip Base64 解码器) |
eyJ | {" | JSON,通常是 JWT 的一段 |
PD94bWwg | <?xml | XML |
更多签名见 常见的 Base64 前缀。对于类型未知的文件,Base64 转文件 会识别格式并进行预览。
字符集:修复乱码
Base64 只保存字节,并不记录是哪种字符集把字符变成了这些字节。解码器默认使用 UTF-8,这对大多数现代数据都是正确的。如果不对,症状也很好辨认:
- 出现
�字符,并提示“部分字节不是有效的 UTF-8”。 文本来自某种传统字符集。Y2Fm6Q==按 UTF-8 读取是caf�,按 ISO-8859-1 或 Windows-1252 读取是café。z/Do4uXy这样的俄文文本需要用 Windows-1251 才能显示为Привет。 - 每个字母后面都有一个点或空隙。 这是 UTF-16,其中每个 ASCII 字母后面跟着一个零字节。
SABlAGwAbABvAA==在 UTF-16LE 中是Hello(Base64 转 UTF-16)。 - 输出中出现
é、ü或’。 解码本身是正确的;文本在被转成 Base64 之前就经过了双重编码:之前某个环节把 UTF-8 误当作 Latin-1 读取,又把结果重新存成了 UTF-8。Y2Fmw4PCqQ==解码后正是café。请在源头修复。
自动检测 会先检查字节序标记,再检查字节是否为有效的 UTF-8,然后检查 UTF-16 的零字节模式。Windows-1251、KOI8-R 这类单字节代码页在任何检测器看来都很相似,如果你知道数据来源,请手动选择。
错误提示及其含义
| 提示 | 常见原因 | 解决办法 |
|---|---|---|
| 位置 21 处有无效字符 “.” | 粘贴了整个 JWT:点号分隔了三个片段 | 解码其中一段,或使用 JWT 解码器 |
位置 8 处有无效字符 "\\" | 从 JSON 中复制的 Base64,其中 / 被转义成了 \/ | 把 \/ 替换为 / |
| 输入混用了标准(+ /)和 URL 安全(- _)字符 | 两个字符串被拼在一起,或者只转换了一半 | 用 Base64URL 转 Base64 统一为一种字母表 |
| 填充符(=)只能出现在最末尾 | 两个 Base64 值粘在了一起,例如 SGk=SGk= | 把它们拆开,分别解码 |
| 长度错误:多了或少了一个字符 | 复制时丢失或多出了一个字符 | 重新复制,或试试 Base64 修复 |
Base64 错误指南 更深入地分析了每种情况。如果想找出字符串中到底是哪个字符或哪处填充出了问题,请使用 Base64 校验器。
在 JavaScript、Python 和命令行中解码 Base64
atob() 返回的是每个字符对应一个字节的“二进制字符串”,所以 UTF-8 文本还需要经过 TextDecoder 这一步。atob 接受缺失的填充,但遇到 URL 安全的 - 和 _ 会抛出 InvalidCharacterError。
const s = "R3LDvMOfZSDwn5GL";
new TextDecoder().decode(Uint8Array.from(atob(s), c => c.charCodeAt(0)));
// "Grüße 👋"
// Node.js accepts both alphabets
Buffer.from(s, "base64").toString("utf8"); // "Grüße 👋"
Buffer.from("8J-Riw", "base64url").toString("utf8"); // "👋"
Python 遇到没有填充的输入会抛出 binascii.Error: Incorrect padding,所以要自己补上填充:
import base64
s = "SGVsbG8"
base64.b64decode(s + "=" * (-len(s) % 4)).decode("utf-8")
# 'Hello'
base64.b64decode("SGVs*bG8=", validate=True)
# binascii.Error: Only base64 data is allowed
如果不加 validate=True,Python 会丢弃 * 并返回 b'Hello'。Node 的 Buffer.from 也是如此,所以一个已损坏的字符串可能会在没有任何报错的情况下被解码。
在命令行中:
printf '%s' 'R3LDvMOfZSDwn5GL' | base64 -d
base64 -d message.b64 > message.bin
第一行输出 Grüße 👋。较旧的 macOS 版本中这个参数写作 -D。各语言的更多细节:JavaScript、Node.js、Python、PHP。
常见问题
怎么解码 Base64 字符串?
把它粘贴到上方的输入框,解码后的文本会立即出现。在代码中,先把 Base64 解码为字节,再按 UTF-8 读取这些字节:Python 中是 base64.b64decode(s).decode(),Node.js 中是 Buffer.from(s, "base64").toString()。
为什么解码后的文本出现 � 或 é 这样的乱码?
� 表示这些字节不是有效的 UTF-8,文本很可能是用其他字符集编码的;请在“字符集”菜单中试试 Windows-1252、Windows-1251 或 UTF-16LE。é 变成 é,则说明文本在被编码之前就已经是乱码了。
没有 = 填充的 Base64 能解码吗?
能。解码器会自己补上缺失的 =,并在状态行中说明。填充只用于补齐最后一组,所以总能根据长度还原。
解码结果是一堆乱码,是 Base64 坏了吗?
更常见的情况是,这些数据其实是一个文件。查看状态行中的“看起来像”一栏:对于图片、PDF、压缩包和其他二进制格式,工具会给出可以预览或保存文件的解码器链接。
Base64 不用密钥就能解密吗?
总是可以。Base64 是一种使用公开字母表的编码,不提供任何保密性。如果解码结果看起来仍然是随机的,说明数据在编码之前已经被加密或压缩过了。