Base64 解码器

/

你的数据 100% 私密 —— Base64 的编码和解码全部在你的设备上完成。

明文
Base64

Base64 是什么?#

Base64 是一种用 64 个 ASCII 字符(A–Z、a–z、0–9,再加上 + 和 /)把二进制数据表示成纯文本的方法。它让图片、密钥、电子邮件附件这类二进制数据,能安全地通过为文本而设计的系统。它是编码,不是加密。

Base64 使用一组固定的 64 个字符的字母表。0 到 63 之间的每个值都恰好对应其中一个字符,任何 3 个字节的二进制数据也因此变成 4 个可读的字符:

数值字符
0–25A–Z26 个大写字母
26–51a–z26 个小写字母
52–610–910 个数字
62–63+ /2 个符号

只有 "=" 符号是例外。它是填充,并非那 64 个数值之一,只用来补齐最后一个块。

你几乎一定已经见过它了。只要二进制数据需要藏在文本里传递,Base64 就会出现:

  • 把小图片或图标直接内嵌到 HTML 或 CSS 中
  • 在 JSON API 响应中夹带二进制数据
  • 编码电子邮件附件(MIME)
  • 把密钥与证书存进 PEM 文件

那个 data URI 技巧长这样,这串长字符串就是整张图片:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

Base64 为什么存在?#

早期的网络协议是为文本、而非原始字节设计的。ASCII 使用 7 个位、128 个字符,用于英文绰绰有余,但对二进制却不行。有些系统会破坏控制字符,或改写换行(把 LF 改成 CR + LF),在传输途中悄悄损坏图片与音频。

Base64 只输出每个系统早已共同认可的字符,借此避开了上述所有问题。Base16 与 Base32 用更小的字母表做同样的事,但 Base64 在保持安全的同时,每个字符能塞进更多数据。这正是它胜出的原因。

Base64 编码的工作原理#

整套方法就是一个思路的重复:取 3 个字节(24 个位),把它们重新切成 4 组各 6 个位,再用字母表查出每一组对应的字符。我们用 "Logto" 这个词手动编码一次。

  1. 用每个字符的 ASCII 码,把它写成 8 位的二进制。
  2. 一次取 3 个字节,这就是 24 个位。
  3. 把同样的 24 个位重新切成 4 组各 6 个位。
  4. 把每组 6 个位当成 0 到 63 的数字来读。
  5. 用这个数字查字母表,得到一个字符。
  6. 若最后一段字节不足 3 个,就用 0 补满剩下的位,并加上 "=",让每个块都保持 4 个字符。

步骤 1. 把每个字符变成 8 位的二进制:

字符ASCII 码二进制
L7601001100
o11101101111
g10301100111
t11601110100
o11101101111

步骤 2. 取前 3 个字节 "Log",把这同样的 24 个位重新切成 4 组各 6 个位:

字节(8 位)
01001100 01101111 01100111
分组(6 位)
010011 000110 111101 100111

步骤 3. 把每组 6 个位当成数字来读,再用这个数字查字母表:

6 位分组数值Base64 字符
01001119T
0001106G
111101619
10011139n

"Logto" 有 5 个字节,不是 3 的倍数。最后两个字节 "to" 会切成 6 + 6 + 4。把最后 4 个位用 0 补成一组 6 个位,再加上一个 "=",补齐这个 4 字符的块:

把各块拼起来:

"Logto"  →  TG9ndG8=

每种语言都内置了它。在 Node.js 中:

const text = 'Logto';
const base64 = Buffer.from(text).toString('base64');
console.log(base64); // TG9ndG8=

从这个过程会得出三条值得记住的规律:

  • 进 3 出 4: 输出长度是把输入向上取整到 4 个字符的倍数,所以编码后的数据总是大约大 33%。
  • "=" 代表填充: 只有在输入不是 3 个字节的倍数时才会出现。
  • 填充透露了余数: 没有 "=" 代表是 3 个字节的倍数,一个 "=" 代表剩 2 个字节,两个 "=" 代表剩 1 个字节。

你什么时候该用 Base64?#

当二进制数据必须通过只能处理文本的通道时,就用 Base64:

  • 内嵌资源: 把小图片或字体内嵌到 HTML/CSS,省去一次请求。
  • 纯文本传输: 把二进制数据放进 JSON、XML,或 URL 查询参数里。
  • 受限字符: 让数据通过那些会被控制字节卡住的系统。

你得到的回报:

  • 到处都能用: 任何支持 ASCII 的系统都能读,不需要协商字符集。
  • 不会损坏任何东西: 在原始字节会被破坏的通道上,输出也能原封不动地留存。

URL 安全的 Base64(Base64URL)#

标准的 Base64 依赖三个会跟 URL、查询字符串、文件名运作方式相冲突的字符:+、/,以及 = 填充。把普通的 Base64 字符串直接放进链接,它可能会以不易察觉的方式出错:

  • + 会变成空格在查询字符串中,许多服务器会把 + 读成空格。于是 ?data=ab+cd 会悄悄变成 "ab cd",字节就错了。
  • / 是路径分隔符值里的 / 可能被当成新的路径片段,而大多数文件系统也根本不允许它出现在文件名里。
  • = 同样是保留字符它在查询字符串中用来分隔键与值,所以结尾的 = 填充会被去掉或误读。

你可以对它们做百分号编码(+ 变成 %2B、/ 变成 %2F、= 变成 %3D),但这会让字符串变长,也很容易不小心重复编码。

Base64URL(RFC 4648 §5)从根源解决了这个问题:把 + 换成 -、把 / 换成 _,并去掉 = 填充。这样的结果可以直接放进 URL、查询参数或文件名,完全不用转义。你会在 URL、文件名,以及许多 Web API 中看到它。

const base64 = 'TG9ndG8=';
const urlSafe = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
console.log(urlSafe); // TG9ndG8

限制(以及一个常见误解)#

Base64 只是一种表示方式,不是天上掉下来的好处。请记住三件事:

  • 大约大 33%: 3 个字节变成 4 个字符,所以编码后的数据大约膨胀三分之一。
  • 会消耗 CPU: 在大量处理或大型负载时,编码与解码并不是免费的。
  • 无法直接阅读: 不透明的字符串会让日志记录与调试更加困难。
Base64 不是加密这是大家最常犯的错。Base64 什么都藏不住,任何人都能用一行代码解码。如果数据是敏感的,请加密它。Base64 只改变外形,从不改变谁能读取它。

常见问题#

Base64 是加密吗?安全吗?

不是。它是使用公开字母表的可逆编码,任何人都能立即解码,完全不增加任何保密性。请改为加密敏感数据。

为什么我的 Base64 字符串大了约 33%?

Base64 把每 3 个字节变成 4 个字符,所以编码后的形式总是比原始字节大约大三分之一。

结尾的 "=" 符号是什么意思?

它们是让输出保持在 4 个字符倍数的填充。一个 "=" 代表输入剩 2 个字节,两个 "=" 代表剩 1 个,没有 "=" 代表长度本来就是 3 个字节的倍数。

Base64 和 Base64URL 有什么区别?

Base64URL 是使用 URL 与文件名安全字母表的同一种编码:- 和 _ 取代 + 和 /,而 = 填充通常会被去掉。它常见于 URL、文件名,以及许多 Web API。

Base64 能编码任何文件,还是只能编码文本?

任何二进制数据都可以:图片、PDF、密钥、可执行文件。Base64 处理的是原始字节,所以原本的内容类型并不重要。

这个工具会把我的数据发送到任何地方吗?

不会。编码与解码完全在你的浏览器中执行。你粘贴的任何内容都不会被上传或记录。

使用 Logto Cloud 解锁更多功能