Base64 编解码:文本/图片/文件
图片转 Base64 嵌入网页、JWT Token 解析、邮件附件传输——Base64 是开发中高频出现的编码方式。本文详解 Base64 的原理、用法和实战场景。
什么是 Base64?
Base64 是一种把二进制数据用 64 个可打印字符表示的编码方式。
字符集
A-Z (26 个)
a-z (26 个)
0-9 (10 个)
+ / (2 个)
共 64 个字符,加上 = 用于末尾填充。
编码原理
把数据每 3 字节(24 位)分成 4 组,每组 6 位,对应 1 个 Base64 字符。
原始 3 字节:01001101 01100101 01110100("Met")
分 4 组: 010011 010110 010101 110100
对应字符: T W V 0
所以 3 字节 → 4 字符,体积增加 33%。
体积膨胀
- 1 KB 文本 → 1.33 KB Base64
- 100 KB 图片 → 133 KB Base64
52tool Base64 工具
工具地址:Base64 编解码
功能
- 文本编解码(支持 UTF-8 中文)
- 文件转 Base64
- Base64 转文件
- 图片转 data URI
- URL 安全 Base64(
-_代替+/) - 浏览器端处理,文件不外传
实战 1:文本编码
输入:
Hello, 世界
输出:
SGVsbG8sIOS4lueVjA==
实战 2:文本解码
输入:
SGVsbG8sIOS4lueVjA==
输出:
Hello, 世界
实战 3:图片转 data URI
上传图片 logo.png,输出:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
可直接嵌入 HTML:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...">
实战 4:URL 安全 Base64
普通 Base64 含 + /,URL 中需转义。URL 安全版用 - _:
普通: SGVsbG8+IOS4lueVjA==
URL安全: SGVsbG8-IOS4lueVjA==
实战场景
场景 1:图片内嵌 HTML
减少 HTTP 请求:
<!-- 普通 -->
<img src="/images/logo.png">
<!-- Base64 内嵌 -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...">
优势:少一次请求
劣势:HTML 体积增大 33%,无法浏览器缓存
适用:小于 4 KB 的小图标、Logo。大图不要用 Base64。
场景 2:CSS 背景图
.icon {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0...);
}
SVG 转 Base64 嵌入 CSS,免单独请求。
场景 3:JWT Token
JWT(JSON Web Token)由三段 Base64URL 组成:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpX...
每段都是 Base64URL 编码的 JSON。参考 52tool JWT 解码器。
场景 4:邮件附件
邮件协议 SMTP 只支持 ASCII,附件需 Base64 编码:
Content-Type: image/png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAA...
场景 5:API 数据传输
二进制数据通过 JSON 传输:
{
"filename": "avatar.png",
"data": "iVBORw0KGgoAAAANSUhEUgAA..."
}
注意体积膨胀 33%。
场景 6:DataURL 缓存
LocalStorage 存图片:
// 上传图片预览
const file = input.files[0];
const reader = new FileReader();
reader.onload = () => {
localStorage.setItem('avatar', reader.result); // data:image/png;base64,...
};
reader.readAsDataURL(file);
场景 7:环境变量存密钥
# .env
API_KEY=SGVsbG8gV29ybGQ=
const apiKey = Buffer.from(process.env.API_KEY, 'base64').toString();
编程实现
JavaScript
// 编码
const encoded = btoa('Hello, 世界');
// 但 btoa 不支持中文,需先转 UTF-8
const encoded = btoa(unescape(encodeURIComponent('Hello, 世界')));
// 解码
const decoded = decodeURIComponent(escape(atob(encoded)));
// 现代浏览器
const encoded = Buffer.from('Hello, 世界', 'utf-8').toString('base64');
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
// 文件转 Base64
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => reader.result; // data:...
Python
import base64
# 编码
encoded = base64.b64encode('Hello, 世界'.encode('utf-8')).decode('ascii')
# 'SGVsbG8sIOS4lueVjA=='
# 解码
decoded = base64.b64decode(encoded).decode('utf-8')
# 文件转 Base64
with open('image.png', 'rb') as f:
encoded = base64.b64encode(f.read()).decode('ascii')
# URL 安全 Base64
encoded = base64.urlsafe_b64encode(b'data').decode('ascii')
Java
import java.util.Base64;
// 编码
String encoded = Base64.getEncoder().encodeToString("Hello, 世界".getBytes("UTF-8"));
// 解码
byte[] decoded = Base64.getDecoder().decode(encoded);
String text = new String(decoded, "UTF-8");
// URL 安全
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
Go
import "encoding/base64"
encoded := base64.StdEncoding.EncodeToString([]byte("Hello, 世界"))
decoded, _ := base64.StdEncoding.DecodeString(encoded)
PHP
$encoded = base64_encode('Hello, 世界');
$decoded = base64_decode($encoded);
SQL
MySQL:
SELECT TO_BASE64('Hello');
SELECT FROM_BASE64('SGVsbG8=');
PostgreSQL:
SELECT encode('Hello', 'base64');
SELECT decode('SGVsbG8=', 'base64');
Base64 变体
标准 Base64
字符集:A-Z a-z 0-9 + /,填充 =。
URL 安全 Base64
字符集:A-Z a-z 0-9 - _,可省略填充。
用于 URL、文件名、JWT。
Base64URL without padding
去掉末尾 =,更短。
Base32
字符集:A-Z 2-7,用于不区分大小写的环境(如 DNS)。
Base85 / Ascii85
更高效(4 字节 → 5 字符 vs Base64 的 3 字节 → 4 字符),但少用。
Base64 的"坑"
坑 1:体积膨胀 33%
100KB 图片 → 133KB Base64 文本。大文件转 Base64 不划算,除非必须。
坑 2:中文乱码
btoa('中文') 报错"InvalidCharacterError"——btoa 只支持 Latin1。
解决:先转 UTF-8:
btoa(unescape(encodeURIComponent('中文')))
或用现代 API:
Buffer.from('中文', 'utf-8').toString('base64')
坑 3:Base64 不是加密
Base64 是编码,不是加密!任何人都能解码。不要用它"加密"密码、密钥。
坑 4:换行符
某些实现每 76 字符插入换行(MIME 标准)。直接拼接可能解码失败:
原文:SGVsbG8...
带换行:SGVsbG8...\n...继续
解码前去掉换行符。
坑 5:填充符 =
= 是填充,必须保留。但有些场景(如 JWT)省略 =。要明确编码规范。
性能考虑
编码速度
100KB 文件 Base64 编码:
- 浏览器 FileReader:< 10ms
- Python base64:< 5ms
- Node Buffer:< 5ms
性能不是瓶颈,体积才是。
数据库存储
- VARCHAR(36) 存 UUID:8 字节
- TEXT 存 Base64 文件:体积 1.33 倍
- BLOB 存原始二进制:体积 1 倍
大文件用 BLOB,小数据用 Base64 字符串。
与其他工具配合
Base64 + JWT
工具:JWT 解码器
JWT 三段都是 Base64URL 编码的 JSON,解码后能看到 payload。
Base64 + 图片
工具:图片转 Base64
图片转 data URI,直接嵌入 HTML/CSS。
Base64 + 哈希
哈希值通常用十六进制表示,但也可用 Base64 表示(更短):
MD5("hello"): hex = 5d41402abc4b2a76b9719d911017c592
MD5("hello"): b64 = XUFBQKvEsqd...
Base64 + 文件传输
工具:文件转换
把文件转 Base64 通过 JSON API 传输。
常见问题解答
Q: Base64 是加密吗?
A: 不是!Base64 是编码,不是加密。任何人都能解码。"base64 加密"是误解。需要安全传输请用 AES 等加密算法。参考 AES 加密解密。
Q: Base64 编码后能压缩吗?
A: 能,但效率低。Base64 文本对压缩算法不友好(已是字符表示)。建议先压缩原始二进制,再 Base64 编码。
Q: 图片转 Base64 后怎么用?
A: 用 data:image/png;base64,... 格式作为 或 CSS url() 的值。注意大图不要转 Base64,会增加 HTML 体积且无法缓存。
Q: JWT 用的 Base64 和普通 Base64 一样吗?
A: 不完全一样。JWT 用 Base64URL(- _ 代替 + /),且去掉末尾填充 =。需要用专用解码工具,如 52tool JWT 解码器。
Q: 文件大小有限制吗?
A: 浏览器端处理,无服务器限制,但受浏览器内存限制。100MB 文件可处理,1GB 文件可能崩溃。大文件建议用桌面工具或脚本处理。
Q: 工具会保存我的文件吗?
A: 52tool Base64 工具在浏览器端处理,不上传服务器。适合处理身份证、合同等敏感文件。
总结
Base64 是开发高频工具:
- 文本编解码 → 52tool Base64
- 图片转 data URI → 图片转 Base64
- JWT 解码 → JWT 解码器
记住:Base64 是编码不是加密,体积膨胀 33%,小图标适合嵌入网页,大文件别用。