当 API 返回一个看起来像 eyJob3N0IjogImRiLXByb2Qi… 的 content 字段, 或者密钥管理器向你提供一个编码后的凭据,又或者你需要提取 JWT 载荷时—— Python base64 解码是你的第一选择。 内置的 base64 模块可以处理所有这些情况,但关于 bytes 与字符串、 URL 安全字母表以及缺失填充的细节几乎让每位开发者都踩过坑—— 我在代码审查中调试过这类错误的次数多到不想承认。 本指南涵盖 base64.b64decode()、urlsafe_b64decode()、 自动填充修复、从文件和 HTTP 响应解码、CLI 工具、 输入验证以及四种常见错误及其修复方案——所有示例均可在 Python 3.8+ 上运行。 如果你只需要快速进行一次解码而不想写代码, ToolDeck 的 Base64 Decode 可在浏览器中即时处理 标准和 URL 安全的 Base64。
- ✓base64.b64decode(s) 是 Python 标准库内置函数——无需安装;它始终返回 bytes,而非 str。
- ✓在 b64decode() 后链式调用 .decode("utf-8") 可将 bytes 转换为 Python 字符串——该函数并不知道原始文本的编码方式。
- ✓对于 URL 安全的 Base64(使用 - 和 _ 代替 + 和 /),请使用 base64.urlsafe_b64decode()——在 JWT、OAuth 令牌和 Google API 凭据中是标准做法。
- ✓使用以下方式修复常见的"Incorrect padding"错误:padded = s + "=" * (-len(s) % 4)——按需添加 0、1 或 2 个字符。
- ✓对来自外部来源的任何输入设置 validate=True,以便在遇到非 Base64 字符时抛出 binascii.Error,而不是静默跳过。
什么是 Base64 解码?
Base64 是一种将任意二进制数据表示为 64 个可打印 ASCII 字符的编码方案:A–Z、a–z、0–9、+ 和 /, 以及用作填充的 =。每 4 个 Base64 字符恰好编码 3 个原始字节, 因此编码后的形式比源数据大约大 33%。 解码则是逆过程——将 ASCII 表示转换回原始字节。
Base64 不加密数据。它纯粹是一种二进制转文本的编码方式——任何人运行解码器都能 完全读取编码后的字符串:
编码前——Base64 编码
eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIiwgInBvcnQiOiA1NDMyLCAidXNlciI6ICJhcHBfc3ZjIn0=解码后
{"host": "db-prod.mycompany.internal", "port": 5432, "user": "app_svc"}base64.b64decode() — 标准库解码
Python 的 base64 模块随标准库一起提供——无需安装,随时可用。 主要函数是 base64.b64decode(s, altchars=None, validate=False)。 它接受 str、bytes 或 bytearray,始终返回 bytes。
最小可运行示例
import base64
import json
# Encoded database config received from a secrets manager
encoded_config = (
"eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIiwgInBvcnQiOiA1NDMyLCAid"
"XNlciI6ICJhcHBfc3ZjIiwgInBhc3N3b3JkIjogInM0ZmVQYXNzITIwMjYifQ=="
)
# Step 1: decode Base64 bytes
raw_bytes = base64.b64decode(encoded_config)
print(raw_bytes)
# b'{"host": "db-prod.mycompany.internal", "port": 5432, "user": "app_svc", "password": "s4fePass!2026"}'
# Step 2: convert bytes → str
config_str = raw_bytes.decode("utf-8")
# Step 3: parse into a dict
config = json.loads(config_str)
print(config["host"]) # db-prod.mycompany.internal
print(config["port"]) # 5432b64decode() 始终返回 bytes——而非字符串。 如果原始数据是文本,请链式调用 .decode("utf-8")。 如果是二进制数据(图像、PDF、gzip 压缩包),则保持 bytes 不变, 直接写入文件或传递给对应的库。扩展示例:sort_keys、ensure_ascii 和严格验证
import base64
import binascii
# Token from an internal event bus — validate strictly (external input)
encoded_event = (
"eyJldmVudCI6ICJvcmRlci5zaGlwcGVkIiwgIm9yZGVyX2lkIjogIk9SRC04ODQ3MiIsICJ"
"0aW1lc3RhbXAiOiAiMjAyNi0wMy0xM1QxNDozMDowMFoiLCAicmVnaW9uIjogImV1LXdlc3QtMSJ9"
)
try:
# validate=True raises binascii.Error on any non-Base64 character
raw = base64.b64decode(encoded_event, validate=True)
event = raw.decode("utf-8")
print(event)
# {"event": "order.shipped", "order_id": "ORD-88472", "timestamp": "2026-03-13T14:30:00Z", "region": "eu-west-1"}
except binascii.Error as exc:
print(f"Invalid Base64: {exc}")
except UnicodeDecodeError as exc:
print(f"Not UTF-8 text: {exc}")解码 URL 安全的 Base64(base64url)
标准 Base64 使用 + 和 /,这两个字符在 URL 中是保留字符。 URL 安全变体(RFC 4648 §5,也称为 “base64url”)将它们替换为 - 和 _。 JWT 令牌、OAuth 2.0 PKCE 挑战、Google Cloud 凭据以及大多数现代 Web 身份验证流程都使用这种编码。
在不调整字母表的情况下将 URL 安全的 Base64 传递给 b64decode() 会静默损坏数据 或抛出 binascii.Error。 请改用 base64.urlsafe_b64decode()——它会自动处理 - → +和 _ → / 的替换。
import base64
import json
# JWT payload segment (the middle part between the two dots)
# JWTs use URL-safe Base64 without trailing "=" padding
jwt_payload_b64 = (
"eyJ1c2VyX2lkIjogMjg5MywgInJvbGUiOiAiYWRtaW4iLCAiaXNzIjogImF1dGgubXljb21w"
"YW55LmNvbSIsICJleHAiOiAxNzQwOTAwMDAwLCAianRpIjogImFiYzEyMzQ1LXh5ei05ODc2In0"
)
# Restore padding before decoding (JWT deliberately omits '=')
padded = jwt_payload_b64 + "=" * (-len(jwt_payload_b64) % 4)
payload_bytes = base64.urlsafe_b64decode(padded)
payload = json.loads(payload_bytes.decode("utf-8"))
print(payload["role"]) # admin
print(payload["iss"]) # auth.mycompany.com
print(payload["user_id"]) # 2893"=" * (-len(s) % 4) 按需精确添加 0、1 或 2 个填充字符, 当字符串已正确填充时此操作无副作用。 这是修复 JWT 和 OAuth 填充问题的惯用 Python 写法。base64.b64decode() 参数参考
以下所有参数均适用于 b64decode() 和 urlsafe_b64decode(), 但 altchars 仅适用于 b64decode()。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| s | bytes | str | bytearray | — | 要解码的 Base64 编码输入;除 bytes 类型外,也接受 ASCII str。 |
| altchars | bytes | None | None | 替换 + 和 / 的 2 字节序列;支持标准 URL 安全变体以外的自定义 Base64 字母表。 |
| validate | bool | False | 为 True 时,遇到 Base64 字母表以外的字符会抛出 binascii.Error;为 False 时,非字母表字节(换行符、空格)会被静默忽略。 |
validate=False 的默认值对于 PEM 格式数据和多行 Base64(换行符很常见)是有意为之的。 对于 API 载荷、用户上传或任何不受信任的输入, 请传入 validate=True 以便尽早捕获损坏或注入的数据并给出清晰的错误信息。
Python Base64 解码填充错误——如何修复
在 Python 中解码 Base64 时最常见的错误是:
import base64
base64.b64decode("eyJ0eXBlIjogImFjY2VzcyJ9")
# binascii.Error: Incorrect paddingBase64 要求字符串长度为 4 的倍数。 当数据通过 URL、HTTP 头或 JWT 库传递时,尾部的 =填充会被剥离以节省字节。有两种可靠的修复方法。
方法 1:内联恢复填充(推荐)
import base64
import json
def b64decode_unpadded(data: str | bytes) -> bytes:
"""Decode Base64 with automatic padding correction."""
if isinstance(data, str):
data = data.encode("ascii")
data += b"=" * (-len(data) % 4)
return base64.b64decode(data)
# Works regardless of how many '=' were stripped
token_a = "eyJ0eXBlIjogImFjY2VzcyJ9" # 0 chars of padding stripped
token_b = "eyJ0eXBlIjogInJlZnJlc2gifQ" # 1 char stripped
token_c = "eyJ0eXBlIjogImFwaV9rZXkifQ==" # already padded
for token in (token_a, token_b, token_c):
result = json.loads(b64decode_unpadded(token).decode("utf-8"))
print(result["type"])
# access
# refresh
# api_key方法 2:用于 OAuth / JWT 的 URL 安全解码加填充
import base64
import json
def decode_jwt_segment(segment: str) -> dict:
"""Decode a single JWT segment (header or payload)."""
# Add padding, use URL-safe alphabet
padded = segment + "=" * (-len(segment) % 4)
raw = base64.urlsafe_b64decode(padded)
return json.loads(raw.decode("utf-8"))
# Google OAuth ID token payload (simplified)
id_token_payload = (
"eyJzdWIiOiAiMTEwNTY5NDkxMjM0NTY3ODkwMTIiLCAiZW1haWwiOiAic2FyYS5jaGVuQGV4"
"YW1wbGUuY29tIiwgImhkIjogImV4YW1wbGUuY29tIiwgImlhdCI6IDE3NDA5MDAwMDB9"
)
claims = decode_jwt_segment(id_token_payload)
print(claims["email"]) # sara.chen@example.com
print(claims["hd"]) # example.com从文件和 API 响应中解码 Base64
从磁盘读取 Base64 和解码 API 载荷是两种最常见的生产场景。 两者都需要适当的错误处理——损坏的填充和意外的二进制类型是真实存在的情况, 而非理论上的边缘情况。
读取并解码 Base64 文件
import base64
import json
from pathlib import Path
def decode_attachment(envelope_path: str, output_path: str) -> None:
"""
Read a JSON envelope with a Base64-encoded attachment,
decode it, and write the binary output to disk.
"""
try:
envelope = json.loads(Path(envelope_path).read_text(encoding="utf-8"))
encoded_data = envelope["attachment"]["data"]
file_bytes = base64.b64decode(encoded_data, validate=True)
Path(output_path).write_bytes(file_bytes)
print(f"Saved {len(file_bytes):,} bytes → {output_path}")
except FileNotFoundError:
print(f"Envelope file not found: {envelope_path}")
except (KeyError, TypeError):
print("Unexpected envelope structure — 'attachment.data' missing")
except base64.binascii.Error as exc:
print(f"Invalid Base64 content: {exc}")
# Example envelope:
# {"attachment": {"filename": "invoice_2026_03.pdf", "data": "JVBERi0xLjQK..."}}
decode_attachment("order_ORD-88472.json", "invoice_2026_03.pdf")从 HTTP API 响应中解码 Base64
import base64
import json
import urllib.request
def fetch_and_decode_secret(vault_url: str, secret_name: str) -> str:
"""
Retrieve a Base64-encoded secret from an internal vault API
and return the decoded plaintext value.
"""
url = f"{vault_url}/v1/secrets/{secret_name}"
req = urllib.request.Request(url, headers={"X-Vault-Token": "s.internal"})
try:
with urllib.request.urlopen(req, timeout=5) as resp:
body = json.loads(resp.read().decode("utf-8"))
# Vault returns: {"data": {"value": "<base64>", "encoding": "base64"}}
encoded = body["data"]["value"]
return base64.b64decode(encoded).decode("utf-8")
except urllib.error.URLError as exc:
raise RuntimeError(f"Vault unreachable: {exc}") from exc
except (KeyError, UnicodeDecodeError, base64.binascii.Error) as exc:
raise ValueError(f"Unexpected secret format: {exc}") from exc
# db_pass = fetch_and_decode_secret("https://vault.internal", "db-prod-password")
# print(db_pass) # s4feP@ss!2026requests 库,将 urllib.request 替换为 resp = requests.get(url, timeout=5, headers=headers) 和 body = resp.json()。Base64 解码逻辑完全相同。命令行 Base64 解码
对于快速的终端检查——验证令牌、查看编码的配置内容, 或将 API 输出通过解码器管道传输——base64 命令在 Linux 和 macOS 上均可用。Python 的内置 -m base64 模块跨平台工作, 包括 Windows。
# Decode a Base64 string and print the result (Linux / macOS)
echo "eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIn0=" | base64 --decode
# {"host": "db-prod.mycompany.internal"}
# Decode a file, save decoded output
base64 --decode encoded_payload.txt > decoded_output.json
# Python's cross-platform CLI decoder (works on Windows too)
python3 -m base64 -d encoded_payload.txt
# Decode a JWT payload segment inline — strip header/signature first
echo "eyJ1c2VyX2lkIjogMjg5MywgInJvbGUiOiAiYWRtaW4ifQ" | python3 -c "
import sys, base64, json
s = sys.stdin.read().strip()
padded = s + '=' * (-len(s) % 4)
print(json.dumps(json.loads(base64.urlsafe_b64decode(padded)), indent=2))
"对于编写 shell 管道感觉过于繁琐的探索性工作, 将字符串粘贴到在线 Base64 解码器—— 它会自动检测 URL 安全输入并即时修复填充。
解码前验证 Base64 输入
当 Base64 数据来自用户输入、Webhook 或不受信任的第三方 API 时, 请在解码前进行验证,以便给出清晰、可操作的错误信息,而不是在业务逻辑深处产生令人困惑的 binascii.Error 堆栈跟踪。 Python 提供两种方式:捕获异常,或使用正则表达式预验证。
import base64
import binascii
import re
# ── Option A: try/except (recommended for most code paths) ──────────────────
def safe_b64decode(data: str) -> bytes | None:
"""Return decoded bytes, or None if the input is not valid Base64."""
try:
padded = data + "=" * (-len(data) % 4)
return base64.b64decode(padded, validate=True)
except (binascii.Error, ValueError):
return None
print(safe_b64decode("not-base64!!")) # None
print(safe_b64decode("eyJ0eXBlIjogInJlZnJlc2gifQ")) # b'{"type": "refresh"}'
# ── Option B: regex pre-validation ──────────────────────────────────────────
# Standard Base64 (alphabet: A-Z a-z 0-9 + /)
_STANDARD_RE = re.compile(r"^[A-Za-z0-9+/]*={0,2}$")
# URL-safe Base64 (alphabet: A-Z a-z 0-9 - _)
_URLSAFE_RE = re.compile(r"^[A-Za-z0-9-_]*={0,2}$")
def is_valid_base64(s: str) -> bool:
"""True if s is a syntactically valid standard Base64 string."""
# Length must be a multiple of 4 for fully padded strings
stripped = s.rstrip("=")
padded = stripped + "=" * (-len(stripped) % 4)
return bool(_STANDARD_RE.match(padded))
print(is_valid_base64("SGVsbG8gV29ybGQ=")) # True
print(is_valid_base64("SGVsbG8gV29ybGQ!")) # False (! is not Base64)高性能替代方案:pybase64
对于绝大多数使用场景,Python 的标准库 base64 模块完全足够。 如果你每秒处理数千个 API 载荷、在紧密循环中解码数兆字节的二进制附件, 或者分析器显示 Base64 操作是性能瓶颈——可以考虑 pybase64。 它是 libbase64 的 C 扩展封装,在处理大输入时通常比标准库实现快 2–5 倍。
pip install pybase64
import pybase64
# Drop-in replacement — identical API to the stdlib base64 module
encoded_image = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIABQ..."
image_bytes = pybase64.b64decode(encoded_image, validate=False)
print(f"Decoded {len(image_bytes):,} bytes")
# URL-safe variant — same as base64.urlsafe_b64decode()
token_bytes = pybase64.urlsafe_b64decode("eyJpZCI6IDQ3MX0=")
print(token_bytes) # b'{"id": 471}'
# Benchmark note: on strings under ~10 KB the function-call overhead dominates
# and the speedup is negligible. Profile before switching.该 API 与 base64 完全相同——只需替换导入,其余代码无需修改。 仅在分析确认 Base64 确实是瓶颈时才使用它, 这种情况在高吞吐量数据管道之外并不常见。
常见错误
我在代码审查中反复见到这四种错误——它们在来自 JavaScript 或 PHP 等语言的开发者中尤为常见, 因为那些语言的 Base64 解码直接返回字符串,或者来自完全跳过错误处理的教程。
错误 1:忘记对结果调用 .decode()
# ❌ b64decode() returns bytes — this crashes downstream
import base64
raw = base64.b64decode("eyJ1c2VyX2lkIjogNDcxLCAicm9sZSI6ICJhZG1pbiJ9")
# TypeError: byte indices must be integers or slices, not str
user_id = raw["user_id"]# ✅ decode bytes → str, then parse
import base64, json
raw = base64.b64decode("eyJ1c2VyX2lkIjogNDcxLCAicm9sZSI6ICJhZG1pbiJ9")
payload = json.loads(raw.decode("utf-8"))
print(payload["user_id"]) # 471
print(payload["role"]) # admin错误 2:对 URL 安全的 Base64 输入使用 b64decode()
# ❌ JWT and OAuth tokens use '-' and '_' — not in standard alphabet import base64 jwt_segment = "eyJ1c2VyX2lkIjogMjg5M30" # binascii.Error or silently wrong bytes — unpredictable behaviour base64.b64decode(jwt_segment)
# ✅ use urlsafe_b64decode() for any token with '-' or '_'
import base64, json
jwt_segment = "eyJ1c2VyX2lkIjogMjg5M30"
padded = jwt_segment + "=" * (-len(jwt_segment) % 4)
data = base64.urlsafe_b64decode(padded)
print(json.loads(data.decode("utf-8")))
# {'user_id': 2893}错误 3:不修复被剥离令牌的填充
# ❌ JWTs and most URL-transmitted tokens strip '=' — this crashes import base64 # Valid JWT payload segment — no padding, as per spec segment = "eyJ0eXBlIjogImFjY2VzcyIsICJqdGkiOiAiMzgxIn0" base64.urlsafe_b64decode(segment) # binascii.Error: Incorrect padding
# ✅ add padding before every urlsafe_b64decode() call
import base64, json
segment = "eyJ0eXBlIjogImFjY2VzcyIsICJqdGkiOiAiMzgxIn0"
padded = segment + "=" * (-len(segment) % 4)
result = json.loads(base64.urlsafe_b64decode(padded).decode("utf-8"))
print(result["type"]) # access
print(result["jti"]) # 381错误 4:对二进制数据调用 .decode("utf-8")
# ❌ Binary files (PDF, PNG, ZIP) are not UTF-8 text — this crashes
import base64
# Base64-encoded PDF starts with JVBERi... (%PDF-)
pdf_b64 = "JVBERi0xLjQKJeLjz9MKNyAwIG9iago8PC9U..."
pdf_text = base64.b64decode(pdf_b64).decode("utf-8")
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2# ✅ write binary directly to a file — no .decode() needed
import base64
from pathlib import Path
pdf_b64 = "JVBERi0xLjQKJeLjz9MKNyAwIG9iago8PC9U..."
pdf_bytes = base64.b64decode(pdf_b64)
Path("report_q1_2026.pdf").write_bytes(pdf_bytes)
print(f"Saved {len(pdf_bytes):,} bytes")在 Python 中解码大型 Base64 文件
使用 Path.read_text() 加载一个 200 MB 的 Base64 文件并一次性解码, 会同时分配编码字符串、解码后的字节以及任何中间表示—— 在内存受限的服务器或 Lambda 函数上很容易耗尽内存。 对于大于约 50–100 MB 的文件,请改用分块方式。
分块解码到磁盘(无需将整个文件加载到内存)
import base64
def decode_large_b64_file(input_path: str, output_path: str, chunk_size: int = 65536) -> None:
"""
Decode a large Base64 file in chunks to avoid loading the entire encoded
string into memory. chunk_size must be a multiple of 4 to keep Base64
block boundaries aligned across reads.
"""
assert chunk_size % 4 == 0, "chunk_size must be a multiple of 4"
bytes_written = 0
with open(input_path, "rb") as src, open(output_path, "wb") as dst:
while True:
chunk = src.read(chunk_size)
if not chunk:
break
# Strip whitespace that may appear in wrapped/multiline Base64
chunk = chunk.strip()
if chunk:
dst.write(base64.b64decode(chunk))
bytes_written += len(chunk)
print(f"Decoded {bytes_written:,} Base64 bytes → {output_path}")
# Example: decode a 300 MB database snapshot stored as Base64
decode_large_b64_file("snapshot_2026_03_13.b64", "snapshot_2026_03_13.sql.gz")使用 base64.decodebytes() 解码 PEM / 多行数据
import base64
# base64.decodebytes() is designed for MIME / PEM Base64 that wraps at 76 chars.
# It silently ignores whitespace and newlines — perfect for certificate files.
with open("server_cert.pem", "rb") as f:
pem_data = f.read()
# Strip PEM headers if present, then decode
lines = [
line for line in pem_data.splitlines()
if not line.startswith(b"-----")
]
raw_cert = base64.decodebytes(b"
".join(lines))
print(f"Certificate DER payload: {len(raw_cert):,} bytes")base64.decodebytes()。 对大型不透明数据块(备份、媒体文件)使用上述分块方式。 对于紧凑的单行令牌(JWT、OAuth), b64decode() 或 urlsafe_b64decode() 始终是正确的选择。Python Base64 解码方法——快速比较
| 方法 | 字母表 | 填充 | 输出 | 需要安装 | 最适用于 |
|---|---|---|---|---|---|
| base64.b64decode() | 标准 (A–Z a–z 0–9 +/) | 必需 | bytes | 否(标准库) | 通用、邮件、PEM |
| base64.decodebytes() | 标准 (A–Z a–z 0–9 +/) | 忽略(剥离空白) | bytes | 否(标准库) | PEM 证书、MIME 附件、多行 Base64 |
| base64.urlsafe_b64decode() | URL 安全 (A–Z a–z 0–9 -_) | 必需 | bytes | 否(标准库) | JWT、OAuth、Google Cloud API |
| base64.b32decode() | 32 字符 (A–Z, 2–7) | 必需 | bytes | 否(标准库) | TOTP 密钥、DNS 安全 ID |
| base64.b16decode() | 十六进制 (0–9, A–F) | 无 | bytes | 否(标准库) | 十六进制编码的校验和、哈希值 |
| pybase64.b64decode() | 标准 (A–Z a–z 0–9 +/) | 必需 | bytes | 是(pip) | 高吞吐量管道、大型载荷 |
| CLI: base64 --decode | 标准 | 自动 | stdout | 否(系统) | 终端快速检查 |
默认使用 b64decode()。一旦在输入中看到 - 或 _, 立即切换到 urlsafe_b64decode()——这些字符是 URL 安全 Base64 的明确标志。 仅在分析确认瓶颈后才使用 pybase64。 在开发过程中进行一次性检查时, ToolDeck 的 Base64 Decode 支持 两种字母表并自动修复填充——无需 Python 环境。
常见问题解答
如何在 Python 中将 Base64 字符串解码为普通字符串?
调用 base64.b64decode(encoded) 获得 bytes,然后对结果调用 .decode("utf-8")以获得 Python str。 这两个步骤始终是分开的,因为 b64decode() 只是逆转 Base64 字母表——它不知道原始内容是 UTF-8、Latin-1 还是二进制。 如果数据使用非 UTF-8 编码,请向 .decode() 传递正确的编解码器名称, 例如 .decode("latin-1")。
为什么在 Python 中解码 Base64 时会出现"Incorrect padding"?
Base64 字符串的长度必须是 4 的倍数。JWT、OAuth 令牌以及通过 URL 传输的数据 经常会剥离尾部的 = 填充。 通过在解码前追加 "=" * (-len(s) % 4) 来修复。 此公式按需精确添加 0、1 或 2 个字符,当字符串已正确填充时是安全的无操作。
Python 中 b64decode() 和 urlsafe_b64decode() 的区别是什么?
两者解码相同的 Base64 算法,但第 62 和第 63 个字符使用不同的字母表。b64decode() 使用 + 和 /; urlsafe_b64decode() 使用 - 和 _。 URL 安全变体在 RFC 4648 §5 中定义,用于 Base64 必须在 URL、HTTP 头或 Cookie 值中 无需百分比编码即可传输的场景。 混淆使用会导致 binascii.Error 或静默的错误输出。
如何在 Python 中解码 Base64 编码的图像?
使用 base64.b64decode(encoded) 解码为 bytes,然后直接将这些字节写入文件——不要对图像数据调用 .decode("utf-8")。 如果输入是数据 URL(例如 data:image/png;base64,iVBORw0KGgo…), 请先剥离前缀:
import base64
from pathlib import Path
# Data URL from an <img src="..."> or an API response
data_url = (
"data:image/png;base64,"
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIABQ=="
)
# Split off the "data:image/png;base64," prefix
_, encoded = data_url.split(",", 1)
image_bytes = base64.b64decode(encoded)
Path("avatar_jsmith.png").write_bytes(image_bytes)
print(f"Saved {len(image_bytes)} bytes")可以在 Python 中不导入任何模块就解码 Base64 吗?
技术上可以,但没有理由这么做。base64 模块是 Python 标准库的一部分,随时可用,始终已安装——它没有依赖项, 其函数以 C 实现。从头重新实现 Base64 会更慢、更容易出错,也更难维护。 始终使用 import base64。
当输入是 bytes 而非字符串时,如何在 Python 中解码 Base64?
base64.b64decode() 可以互换地接受 str、bytes 和 bytearray——无需转换。 如果你从 socket 或文件读取中收到 b"SGVsbG8=",直接传入即可。 填充修复在 bytes 模式下同样有效: data + b"=" * (-len(data) % 4)。
相关工具
- Base64 Encode — 即时将文本或二进制文件编码为 Base64;无需运行脚本即可为 Python 解码代码生成测试数据。
- JWT Decoder — 无需编写代码即可查看 JWT 头部和载荷;载荷在底层使用 URL 安全 Base64 解码, 与上面示例中展示的完全一致。
- URL Decode — 对查询字符串和路径段进行百分比解码;在解析 OAuth 回调 URL 或 Webhook 载荷时 经常需要与 Base64 解码配合使用。
- URL Encode — 对特殊字符进行百分比编码;当需要将 Base64 编码的值安全地嵌入 URL 查询参数时很有用。