ToolPal
计算机屏幕上显示的编程代码

Base64编码完全指南 — 概念与实践

📷 Luis Gomes / Pexels

Base64编码完全指南 — 概念与实践

了解什么是Base64编码、它如何工作以及何时使用。包含实际示例和免费的在线编码器/解码器工具。

D作者: Daniel Park2026年3月14日2分钟阅读

什么是Base64编码?

Base64是一种二进制到文本的编码方案,将二进制数据表示为ASCII字符串。它将二进制数据转换为64种可打印字符 — A-Z、a-z、0-9、+/ — 使其可以安全地通过基于文本的协议传输。

"Base64"这个名称来源于恰好使用了64种不同的ASCII字符。这是有意为之的设计:64是2的幂(2^6),使二进制和Base64之间的转换简单而高效。

如果你做过任何Web开发,几乎可以肯定你已经在不知不觉中遇到过Base64。那些以一两个=号结尾的看似随机的长字符串?很可能就是Base64。

为什么使用Base64?

Base64解决的核心问题很简单。许多系统和协议设计为只处理文本 — 它们无法可靠地传递原始二进制数据。如果你通过只支持ASCII文本的电子邮件协议发送JPEG图像,数据会被损坏,因为某些字节值在文本协议中具有特殊含义。

Base64通过将所有数据转换为安全的可打印ASCII字符来解决这个问题。

  • 电子邮件附件:MIME使用Base64在电子邮件中编码二进制文件
  • 数据URI:直接在HTML或CSS中嵌入图像,无需额外的HTTP请求
  • API认证:HTTP Basic Auth用Base64编码凭据
  • JWT令牌:JSON Web Tokens对其头部和载荷使用Base64URL编码
  • 配置文件:在YAML或JSON文本文件中安全存储二进制数据(证书、密钥)
  • 数据库存储:在基于文本的列中保存小型二进制值
  • URL参数:通过URL查询字符串安全传递二进制数据

Base64的工作原理

逐步分解编码过程,便于理解:

  1. 获取二进制数据(例如,将文本转换为ASCII字节)
  2. 将其分割为6位组(而不是通常的8位字节)
  3. 将每个6位组映射到64个字符之一
  4. 如果数据不能被3字节组整除,则添加填充字符(=

Base64字母表

标准Base64字母表由以下部分组成:

  • A-Z(索引0-25)
  • a-z(索引26-51)
  • 0-9(索引52-61)
  • +(索引62)
  • /(索引63)
  • =用于填充

分步示例

让我们手动编码文本Hi

步骤1:转换为ASCII字节 H = 72,i = 105

步骤2:转换为二进制 72 = 01001000105 = 01101001

步骤3:连接所有位 01001000 01101001

步骤4:重新分组为6位块 010010 000110 1001xx

我们只有16位,所以最后一组用零填充:010010 000110 100100

步骤5:将每个6位值映射到Base64字母表

  • 010010 = 18 = S
  • 000110 = 6 = G
  • 100100 = 36 = k

步骤6:添加填充 原始输入为2字节(不是3的倍数),所以附加一个=填充字符。

结果:SGk=

理解填充

填充是Base64中比较令人困惑的部分之一。规则如下:

  • 如果输入长度可被3整除:无填充
  • 如果剩余1个字节:附加==
  • 如果剩余2个字节:附加=

示例:

  • A(1字节)→ QQ==
  • AB(2字节)→ QUI=
  • ABC(3字节)→ QUJD(无填充)

实际使用场景

在HTML中嵌入图像(数据URI)

Base64最实用的用途之一是将小图像直接内联到HTML或CSS中,消除额外的HTTP请求。这对小图标和装饰性元素很有用。

<img src="data:image/png;base64,iVBORw0KGgo..." />
.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxu...");
}

何时使用:对于小于2-3KB的图像(小图标或1×1跟踪像素),节省一次网络往返实际上可以提升性能。对于更大的图像,33%的大小增加和浏览器缓存的丧失使其得不偿失。

HTTP基本认证

当服务器需要Basic Auth时,客户端用冒号连接用户名和密码,并将结果用Base64编码:

username:password → dXNlcm5hbWU6cGFzc3dvcmQ=

请求头如下所示:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

这是编码,不是加密。任何截获此头的人都可以立即解码凭据。这就是为什么Basic Auth只能通过HTTPS使用。

在JSON中存储二进制数据

JSON原生不支持二进制数据。当你需要在JSON文档中包含文件、图像或二进制载荷时,Base64是标准方法:

{
  "file": "SGVsbG8gV29ybGQ=",
  "filename": "hello.txt",
  "mimetype": "text/plain"
}

这种模式在接受JSON请求体(而不是多部分表单数据)的文件上传REST API中很常见。

JWT令牌

JSON Web Tokens使用称为Base64URL的变体,将+替换为-/替换为_,并省略填充。JWT由三个用点分隔的Base64URL编码部分组成:

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiam9obiJ9.abc123signature

解码第一部分得到头部:{"alg":"HS256"}。解码第二部分得到载荷:{"user":"john"}

电子邮件附件

当你发送带附件的电子邮件时,二进制文件被Base64编码并包含在MIME消息体中。你的电子邮件客户端自动处理这个过程,但在底层,附件数据以Base64文本的形式出现,按照MIME规范分成76字符的行。

Base64 vs Base64URL

实际上有两种常见的Base64变体,混淆它们经常导致错误:

属性标准Base64Base64URL
字符62-63+/-_
填充必需(=通常省略
用途MIME、通用编码URL、JWT、文件名

Base64URL存在的原因是+/=在URL中都有特殊含义。如果将标准Base64编码的字符串放入查询参数中,+会被解释为空格,/会破坏URL路径,=会与键值语法冲突。

Base64 vs 加密

重要:Base64不是加密。它是一种编码方案,任何人都可以解码它。永远不要单独使用Base64来保护敏感数据。

这个错误经常出现。开发者用Base64编码API密钥或密码,以为它被隐藏了。其实没有。打开浏览器的开发者工具,将字符串粘贴到atob()中,原始值立即出现。

如果你需要保护数据,请使用适当的加密(AES、RSA)或哈希(SHA-256、bcrypt)。Base64用于传输兼容性,不用于安全。

常见错误和陷阱

1. 忽略33%的大小增加

每3个字节的输入产生4个字节的输出。将1MB图像内联为Base64意味着发送约1.33MB的数据,浏览器无法单独缓存该图像。对于大文件,这种开销会累积。

2. MIME行长度

MIME标准要求Base64编码的数据分成76字符的行。如果你手动构造电子邮件或MIME消息并跳过换行,某些邮件服务器会拒绝或损坏消息。

3. 混淆Base64和Base64URL

用标准Base64解码器解码JWT令牌可能失败或产生错误结果,因为字符集不同。始终验证你使用的是哪个变体。

4. 双重编码

一个惊人常见的错误:对已经编码的数据再次编码。如果你Base64编码一个字符串,然后不小心再次编码,结果是有效的Base64 — 但解码一次得到的是第一次编码的字符串,而不是原始内容。如果解码后的输出看起来像Base64,你在某处进行了双重编码。

5. 字符编码混乱

Base64编码的是原始字节,不是字符。当涉及重音字符时,UTF-8中的字符串和ISO-8859-1中的相同字符串可能不同。在Base64编码文本之前,始终明确字符编码。

在不同语言中使用Base64

JavaScript(浏览器)

// 编码
const encoded = btoa("Hello World");  // "SGVsbG8gV29ybGQ="

// 解码
const decoded = atob("SGVsbG8gV29ybGQ=");  // "Hello World"

注意:btoaatob只适用于ASCII字符串。对于Unicode文本,先编码为UTF-8:

// 编码Unicode文本
const encoded = btoa(unescape(encodeURIComponent("你好")));

// 解码
const decoded = decodeURIComponent(escape(atob(encoded)));

Python

import base64

# 编码
encoded = base64.b64encode(b"Hello World").decode()  # "SGVsbG8gV29ybGQ="

# 解码
decoded = base64.b64decode("SGVsbG8gV29ybGQ=").decode()  # "Hello World"

# Base64URL变体
url_encoded = base64.urlsafe_b64encode(b"Hello World").decode()

命令行

# 编码
echo -n "Hello World" | base64
# SGVsbG8gV29ybGQ=

# 解码
echo "SGVsbG8gV29ybGQ=" | base64 --decode
# Hello World

echo-n标志很重要。没有它,换行符也会被编码,产生不同的结果。

性能考虑

Base64编码和解码是快速操作,但在性能敏感的情况下大小很重要:

  • 大文件传输:33%的开销会累积。10MB的文件编码后约为13.3MB。如果频繁传输文件,请使用二进制协议或多部分上传。
  • 内联CSS图像:嵌入在样式表中的Base64编码图像会在每次页面加载时重新下载。对于小于2KB的图标没问题,但更大的图像应该是单独的文件,以便浏览器可以缓存。
  • 数据库存储:在文本列中存储Base64可以工作,但比在二进制/blob列中存储原始字节多使用33%的空间。在规模上,这个存储成本是显著的。

不应该使用Base64的情况

  • 加密敏感数据 — 它完全没有安全性
  • 将大文件作为数据URI — 大小开销和缺乏缓存损害性能
  • 当二进制传输可用时 — 如果协议原生支持二进制数据(HTTP多部分、gRPC、二进制模式WebSocket),没有理由增加Base64开销
  • 在数据库中存储大文件 — 改用blob或二进制列

立即尝试

使用免费的Base64编码器/解码器立即编码或解码Base64字符串。所有处理都在你的浏览器中进行 — 你的数据永远不会离开你的设备。

常见问题

D

关于作者

Daniel Park

Senior frontend engineer based in Seoul. Seven years of experience building web applications at Korean SaaS companies, with a focus on developer tooling, web performance, and privacy-first architecture. Open-source contributor to the JavaScript ecosystem and founder of ToolPal.

了解更多

分享文章

XLinkedIn

相关文章