🏠 首页 攻略 Base64编码解码完全指南:从原理到实战的5个高频场景

Base64编码解码完全指南:从原理到实战的5个高频场景

Base64是什么?为什么URL里一堆乱码都是它?本文从Base64编码原理讲起,演示5个高频使用场景:图片转Base64、URL安全编码、文件加密传输、API签名验证、以及常见错误排查,附代码示例。

你在浏览器里见过这样的字符串吗?

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...

这一长串乱码,就是 Base64。

它看起来像乱码,但背后有个简单的设计思路:把二进制数据变成 printable 字符。

这篇文章从 Base64 的原理讲起,演示 5 个你在实际开发中经常遇到的场景。每个场景都有代码示例,可以直接拿去用。

Base64 到底是什么?

把一段话说清楚:Base64 是一种编码方式,不是加密方式。

编码和加密的区别:

  • 编码:任何人都能解码,目的是让数据能在特定渠道传输
  • 加密:只有持有密钥的人能解码,目的是保护隐私

Base64 把每 3 个字节(24 位)的数据,转换成 4 个可打印字符。这 4 个字符来自 64 个预设字符:A-Z、a-z、0-9、+、/。

为什么是 64 个字符?因为 2^6 = 64。6 位二进制可以表示 64 种状态,正好对应一个 Base64 字符。

转换过程很简单:

原始 3 字节:  01234567 89abcdef 01234567
按6位分组:    012345 6789ab cdef01 234567
对应字符:       T        G        1        j

输出 4 个字符,输入 3 个字节。所以 Base64 编码后的数据比原始数据大约 33%。

场景1:把图片转成 Base64 直接嵌入 HTML

这是最常见的用法。不需要上传图片到服务器,直接把图片数据写在 HTML 里。

import base64

# 读取图片文件
with open('photo.png', 'rb') as f:
    image_data = f.read()

# 转成 Base64
b64_string = base64.b64encode(image_data).decode('utf-8')

# 嵌入 HTML
html = f'''
<img src="data:image/png;base64,{b64_string}" alt="图片">
'''

with open('image_inlined.html', 'w') as f:
    f.write(html)

注意事项:

  • 图片越大,HTML 文件越大。超过 100KB 的图片不建议内嵌
  • 移动端加载内嵌图片会比较慢
  • 适合小图标、logo 这类小图片

场景2:URL 安全 Base64 编码

标准 Base64 用了 +/ 字符。这两个字符在 URL 中有特殊含义,会导致问题。

解决方法:用 - 替换 +,用 _ 替换 /,去掉末尾的 =

import base64

# 普通 Base64 编码
normal_b64 = base64.b64encode(b'hello world!').decode()
# 结果: aGVsbG8gd29ybGQh

# URL 安全的 Base64 编码
url_safe = base64.urlsafe_b64encode(b'hello world!').decode()
# 结果: aGVsbG8gd29ybGQh

# 去掉末尾的 = 填充符(可选)
url_safe = url_safe.rstrip('=')

什么时候用 URL 安全 Base64?

  • 生成短链接参数
  • JWT token 传递
  • API 查询参数
  • URL 中传输任意数据

场景3:用 Base64 做简单的 API 参数传输

假设你要通过 URL 参数传一个 JSON 对象给服务端:

import base64
import json

# 原始数据
data = {
    "user_id": 12345,
    "permissions": ["read", "write", "delete"],
    "expires": "2026-12-31"
}

# 编码
encoded = base64.urlsafe_b64encode(json.dumps(data).encode()).decode().rstrip('=')

print(encoded)
# 结果类似: eyJ1c2VyX2lkIjoxMjM0NSwicGVybWlzc2lvbnMiOlsicmVhZCIsIndyaXRlIiwiZGVsZXRlIl0sImV4cGlyZXMiOiIyMDI2LTEyLTMxIn0

# 解码
decoded = base64.urlsafe_b64decode(encoded + '==')
result = json.loads(decoded)
print(result)
# {'user_id': 12345, 'permissions': ['read', 'write', 'delete'], 'expires': '2026-12-31'}

注意: Base64 编码不等于加密。任何人都能看到你的数据内容。如果需要保密,先加密再编码。

场景4:API 签名验证中的 Base64

很多 API 的签名验证流程会用到 Base64。比如 HMAC-SHA256 签名:

import hmac
import hashlib
import base64

def create_signature(secret_key, message):
    """用 HMAC-SHA256 生成签名"""
    signature = hmac.new(
        secret_key.encode('utf-8'),
        message.encode('utf-8'),
        hashlib.sha256
    ).digest()
    # Base64 编码后传给服务端
    return base64.b64encode(signature).decode('utf-8')

# 使用示例
secret = "my_api_secret_key"
message = "GET /api/v1/users 2026-06-10T09:00:00Z"

sig = create_signature(secret, message)
print(sig)
# 把 sig 放在请求头里:Authorization: Bearer <sig>

这是很多 API 的标准做法:

  1. 服务端和客户端共享一个密钥
  2. 客户端用密钥对请求内容做签名
  3. 签名用 Base64 编码后放入请求头
  4. 服务端用同样的密钥验证签名

场景5:常见错误排查

用 Base64 踩过的那些坑:

错误1:字符数不对

import base64

# Base64 编码后的字符串长度必须是 4 的倍数
# 如果不是,需要补 = 填充
bad_string = "aGVsbG8gd29ybGQ"  # 15 个字符,不是 4 的倍数

# 修复方法
padding = 4 - (len(bad_string) % 4)
if padding != 4:
    bad_string += '=' * padding

result = base64.b64decode(bad_string).decode()
print(result)  # hello world

错误2:URL 传输时 + 被转成了空格

这是老式 URL 编码的坑。+application/x-www-form-urlencoded 中会被转成空格。

import urllib.parse
import base64

# 编码
b64 = base64.urlsafe_b64encode(b'test data').decode()

# 用 URL 安全的方式传输
url_encoded = urllib.parse.quote(b64, safe='')

# 解码回来
decoded_b64 = urllib.parse.unquote(url_encoded)
result = base64.urlsafe_b64decode(decoded_b64).decode()
print(result)  # test data

错误3:中文字符直接 Base64 编码乱码

import base64

# 错误做法(直接对中文字符串编码)
wrong = base64.b64encode('你好世界'.encode()).decode()
# 结果: 5L2g5aW95bel5LiA

# 正确做法(先确保 UTF-8 编码)
correct = base64.b64encode('你好世界'.encode('utf-8')).decode()
# 结果: 5L2g5aW95bel5LiA

# 解码回来
print(base64.b64decode(correct).decode('utf-8'))  # 你好世界

记住: 中文字符串在 Base64 编码前,先确认编码格式是 UTF-8。

Base64 vs 其他编码方式

编码方式用途可读性压缩率适合场景
Base64二进制转文本不可读-33%传输、嵌入
Hex二进制转十六进制不可读+100%哈希值显示
UTF-8字符编码部分可读可变文本存储
Gzip+Base64压缩后编码不可读压缩后变小大数据传输

总结

Base64 不是什么高深的技术,但它的实用场景非常广。从图片内嵌、API 签名到 URL 参数传输,你几乎每天都在用它。

核心要点记住三点:

  1. Base64 不是加密,只是编码,任何人都能解码
  2. URL 传输记得用 urlsafe_b64encode,别被 +/ 坑了
  3. 长度问题:解码前先确保字符串长度是 4 的倍数

你有用 Base64 踩过什么坑?分享一下,让后来者少踩几个。