Base64 是將二進位資料編碼為可列印 ASCII 字元的標準方法,廣泛應用於 Email 附件、HTTP 傳輸、Cookie、Data URI 等場景。本文詳細解析原理、標準與 URL-safe 變體、Padding 處理、自定義字母表,並提供 Python 實戰範例。
A-Z a-z 0-9 + /
import base64
# 編碼:bytes -> bytes
data = b'binary\x00string'
encoded = base64.b64encode(data)
print(encoded) # b'YmluYXJ5AHN0cmluZw=='
# 解碼:bytes -> bytes
decoded = base64.b64decode(encoded)
print(decoded) # b'binary\x00string'
# 字串處理流程
text = 'Hello 世界'
encoded_str = base64.b64encode(text.encode('utf-8')).decode('ascii')
print(encoded_str) # 'SGVsbG8g5LiW55WM'
decoded_text = base64.b64decode(encoded_str).decode('utf-8')
print(decoded_text) # 'Hello 世界'
標準 Base64 的 + / 在 URL 中有特殊含義,需替換:
>>> base64.b64encode(b'\xfb\x1d\xfb\xef\xff')
b'abcd++//'
>>> base64.urlsafe_b64encode(b'\xfb\x1d\xfb\xef\xff')
b'abcd--__'
>>> base64.urlsafe_b64decode(b'abcd--__')
b'\xfb\x1d\xfb\xef\xff'
對照表:+ → -,/ → _,其餘相同。
Base64 長度必為 4 的倍數,不足補 =。某些場景(Cookie、URL 參數)會移除 Padding:
>>> base64.b64encode(b'abcd')
b'YWJjZA=='
>>> base64.b64decode(b'YWJjZA') # 缺 Padding
TypeError: Incorrect padding
def safe_b64decode(data: bytes) -> bytes:
"""接受缺 Padding 的 Base64,自動補齊解碼"""
# 補齊至 4 的倍數
padding_needed = 4 - (len(data) % 4) if len(data) % 4 else 0
data += b'=' * padding_needed
return base64.b64decode(data)
# 測試
print(safe_b64decode(b'YWJjZA')) # b'abcd'
print(safe_b64decode(b'YWJjZA==')) # b'abcd'
print(safe_b64decode(b'YWJjZA=')) # b'abcd'
標準庫不直接支援,需自行實作映射表。注意:Base64 非加密,自定義字母表僅是混淆,無安全性可言。
| 場景 | 用途 | 注意事項 |
|---|---|---|
| Email 附件 (MIME) | 二進位附件嵌入郵件本文 | 每 76 字元換行 (RFC 2045) |
| Data URI | <img src="data:image/png;base64,..."> | 小圖片內聯,減少 HTTP 請求 |
| JWT Token | Header.Payload.Signature 三段皆為 Base64URL | 不含 Padding |
| Basic Auth | Authorization: Basic base64(user:pass) | 非加密,必須配合 HTTPS |
| Cookie 序列化 | 將 dict 序列化為字串存入 Cookie | 注意大小限制 (4KB)、移除 Padding |
.encode('utf-8').decode('ascii') 才能當字串用base64.encodebytes() / decodebytes() 搭配檔案流import base64
def encode_file_stream(input_path, output_path, chunk_size=8192):
"""串流編碼大檔案,避免記憶體爆炸"""
with open(input_path, 'rb') as infile, open(output_path, 'wb') as outfile:
encoder = base64._encoder() # 內部增量編碼器
while True:
chunk = infile.read(chunk_size)
if not chunk:
break
outfile.write(encoder.encode(chunk))
outfile.write(encoder.encode(b'', final=True))
def decode_file_stream(input_path, output_path, chunk_size=8192):
with open(input_path, 'rb') as infile, open(output_path, 'wb') as outfile:
decoder = base64._decoder()
while True:
chunk = infile.read(chunk_size)
if not chunk:
break
outfile.write(decoder.decode(chunk))
outfile.write(decoder.decode(b'', final=True))
Base64 是二進位與文字世界的橋樑,掌握 b64encode/b64decode、urlsafe_* 變體、Padding 處理與串流處理,能應對絕大多數編碼傳輸需求。記住:它是編碼,不是加密。