Python’s base64 module encodes binary data as printable ASCII. import base64. b64encode: base64.b64encode(b"data") → b"ZGF0YQ==". b64decode: base64.b64decode(b"ZGF0YQ==") → b"data". urlsafe_b64encode: uses - and _ instead of + and / — safe in URLs and filenames. urlsafe_b64decode: decodes URL-safe encoding. b16encode: base64.b16encode(b"\xff") → b"FF" — hex. b16decode: base64.b16decode(b"FF") → b"\xff". b32encode / b32decode: RFC 4648 base32 (A-Z + 2-7), used in TOTP/OTP. b85encode / b85decode: ASCII85 variant, more compact than base64 (~25% overhead vs 33%). encodebytes: base64.encodebytes(data) — inserts newline every 76 chars (MIME). decodebytes: strips newlines then decodes. Padding: base64 output is always a multiple of 4 bytes — == and = are padding. Strip padding: .rstrip(b"="). Add padding: s += b"=" * (-len(s) % 4). decode with validate: base64.b64decode(s, validate=True) — raises binascii.Error on non-base64 chars. base64.b64decode(s, altchars=b"-_") — custom alphabet. Data URI: f"data:image/png;base64,{base64.b64encode(png_bytes).decode()}". Claude Code generates data URI builders, JWT base64url encoders, TOTP secret formatters, and binary HTTP payload encoders.
CLAUDE.md for base64
## base64 Stack
- Stdlib: import base64
- Standard: base64.b64encode(data).decode() — string; b64decode(s.encode())
- URL-safe: base64.urlsafe_b64encode(data).rstrip(b"=").decode()
- Hex: base64.b16encode(data).decode().lower()
- Data URI: f"data:{mime};base64,{base64.b64encode(data).decode()}"
- Validate: base64.b64decode(s, validate=True) — raises on bad chars
base64 Encoding Pipeline
# app/b64util.py — encode, decode, URL-safe, data URIs, JWT-base64url, MIME
from __future__ import annotations
import base64
import binascii
import mimetypes
from pathlib import Path
from typing import Union
# ─────────────────────────────────────────────────────────────────────────────
# 1. Standard base64 helpers
# ─────────────────────────────────────────────────────────────────────────────
def encode(data: bytes) -> str:
"""
Encode bytes to standard base64 string (with padding and + / chars).
Example:
s = encode(b"Hello, World!") # "SGVsbG8sIFdvcmxkIQ=="
"""
return base64.b64encode(data).decode()
def decode(s: str | bytes) -> bytes:
"""
Decode a standard base64 string to bytes.
Adds padding automatically if missing.
Example:
b = decode("SGVsbG8sIFdvcmxkIQ==") # b"Hello, World!"
b = decode("SGVsbG8sIFdvcmxkIQ") # padding optional
"""
if isinstance(s, str):
s = s.encode()
s = s + b"=" * (-len(s) % 4)
return base64.b64decode(s)
def decode_safe(s: str | bytes, default: bytes | None = None) -> bytes | None:
"""
Decode base64 string; return default on any error.
Example:
data = decode_safe(untrusted_header_value, default=b"")
"""
try:
return decode(s)
except (binascii.Error, ValueError):
return default
def is_valid_base64(s: str | bytes) -> bool:
"""
Return True if s is valid standard base64.
Example:
is_valid_base64("SGVsbG8=") # True
is_valid_base64("not!b64") # False
"""
try:
if isinstance(s, str):
s = s.encode()
padded = s + b"=" * (-len(s) % 4)
base64.b64decode(padded, validate=True)
return True
except (binascii.Error, ValueError):
return False
# ─────────────────────────────────────────────────────────────────────────────
# 2. URL-safe base64 (JWT / token style)
# ─────────────────────────────────────────────────────────────────────────────
def urlsafe_encode(data: bytes, padding: bool = False) -> str:
"""
Encode bytes to URL-safe base64 (uses - and _ instead of + and /).
Strips padding by default (JWT convention).
Example:
token = urlsafe_encode(secrets.token_bytes(32))
"""
encoded = base64.urlsafe_b64encode(data).decode()
return encoded if padding else encoded.rstrip("=")
def urlsafe_decode(s: str | bytes, padding: bool = False) -> bytes:
"""
Decode URL-safe base64 string.
Adds padding automatically.
Example:
data = urlsafe_decode("SGVsbG8")
"""
if isinstance(s, bytes):
s = s.decode()
if not padding:
s = s + "=" * (-len(s) % 4)
return base64.urlsafe_b64decode(s)
def jwt_base64url_encode(data: bytes) -> str:
"""
JWT-conformant base64url (no padding, URL-safe alphabet).
Example:
header_encoded = jwt_base64url_encode(json.dumps(header).encode())
"""
return urlsafe_encode(data, padding=False)
def jwt_base64url_decode(s: str) -> bytes:
"""Decode JWT base64url segment."""
return urlsafe_decode(s, padding=False)
# ─────────────────────────────────────────────────────────────────────────────
# 3. Other encodings
# ─────────────────────────────────────────────────────────────────────────────
def hex_encode(data: bytes) -> str:
"""Encode bytes to lowercase hex string via base64.b16encode."""
return base64.b16encode(data).decode().lower()
def hex_decode(s: str) -> bytes:
"""Decode hex string to bytes."""
return base64.b16decode(s.upper())
def b32_encode(data: bytes, padding: bool = True) -> str:
"""
Encode bytes as base32 (RFC 4648). Used in TOTP/OTP secrets.
Example:
secret = b32_encode(secrets.token_bytes(20)) # TOTP secret
"""
encoded = base64.b32encode(data).decode()
return encoded if padding else encoded.rstrip("=")
def b32_decode(s: str) -> bytes:
"""Decode base32 string."""
padded = s.upper() + "=" * (-len(s) % 8)
return base64.b32decode(padded)
def b85_encode(data: bytes) -> str:
"""
Encode bytes as base85 (~25% overhead vs ~33% for base64).
Suitable for configuration files and compact binary literals.
Example:
compact = b85_encode(uuid_bytes)
"""
return base64.b85encode(data).decode()
def b85_decode(s: str | bytes) -> bytes:
"""Decode base85 string."""
if isinstance(s, str):
s = s.encode()
return base64.b85decode(s)
# ─────────────────────────────────────────────────────────────────────────────
# 4. Data URIs
# ─────────────────────────────────────────────────────────────────────────────
def to_data_uri(data: bytes, mime_type: str) -> str:
"""
Build a base64 data URI for inline embedding in HTML/CSS.
Example:
uri = to_data_uri(png_bytes, "image/png")
html = f'<img src="{uri}">'
"""
encoded = base64.b64encode(data).decode()
return f"data:{mime_type};base64,{encoded}"
def file_to_data_uri(path: str | Path) -> str:
"""
Read a file and return its data URI with auto-detected MIME type.
Example:
uri = file_to_data_uri("logo.svg")
uri = file_to_data_uri("icon.png")
"""
p = Path(path)
mime, _ = mimetypes.guess_type(str(p))
mime = mime or "application/octet-stream"
return to_data_uri(p.read_bytes(), mime)
def from_data_uri(uri: str) -> tuple[str, bytes]:
"""
Parse a data URI and return (mime_type, raw_bytes).
Example:
mime, data = from_data_uri("data:image/png;base64,iVBORw...")
"""
if not uri.startswith("data:"):
raise ValueError("Not a data URI")
meta, _, encoded = uri.partition(",")
mime = meta.split(":")[1].split(";")[0]
data = base64.b64decode(encoded)
return mime, data
# ─────────────────────────────────────────────────────────────────────────────
# 5. MIME / multiline encoding
# ─────────────────────────────────────────────────────────────────────────────
def mime_encode(data: bytes) -> str:
"""
Encode bytes as MIME base64 (76-char line length with newlines).
Used in email attachments and PEM files.
Example:
pem_body = mime_encode(der_bytes)
"""
return base64.encodebytes(data).decode()
def mime_decode(s: str) -> bytes:
"""Decode MIME base64 (handles embedded newlines)."""
return base64.decodebytes(s.encode())
def pem_wrap(data: bytes, label: str = "CERTIFICATE") -> str:
"""
Wrap DER bytes in PEM armor.
Example:
pem = pem_wrap(cert_der, "CERTIFICATE")
"""
body = "\n".join(
base64.b64encode(data[i: i + 48]).decode()
for i in range(0, len(data), 48)
)
return f"-----BEGIN {label}-----\n{body}\n-----END {label}-----\n"
# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
import secrets
print("=== base64 demo ===")
data = b"Hello, \x00World!\xff"
print("\n--- standard encode/decode ---")
encoded = encode(data)
print(f" encode: {encoded!r}")
print(f" decode: {decode(encoded)!r}")
print(f" roundtrip: {decode(encoded) == data}")
print("\n--- decode_safe ---")
print(f" valid: {decode_safe('SGVsbG8=')!r}")
print(f" invalid: {decode_safe('not!base64', default=b'')!r}")
print("\n--- is_valid_base64 ---")
for s in ["SGVsbG8=", "SGVsbG8", "not b64!", ""]:
print(f" {s!r:20s}: {is_valid_base64(s)}")
print("\n--- URL-safe base64 ---")
token = secrets.token_bytes(32)
us_enc = urlsafe_encode(token)
print(f" urlsafe (no padding): {us_enc!r}")
print(f" roundtrip: {urlsafe_decode(us_enc) == token}")
print(f" JWT encode: {jwt_base64url_encode(b'{\"alg\":\"HS256\"}')!r}")
print("\n--- hex / b32 / b85 ---")
sample = b"\xde\xad\xbe\xef"
print(f" b16: {hex_encode(sample)!r} back: {hex_decode(hex_encode(sample))!r}")
print(f" b32: {b32_encode(sample, padding=False)!r}")
print(f" b85: {b85_encode(sample)!r} back: {b85_decode(b85_encode(sample))!r}")
print("\n--- data URI ---")
png_header = b"\x89PNG\r\n\x1a\n"
uri = to_data_uri(png_header, "image/png")
print(f" uri: {uri[:50]}...")
mime, back = from_data_uri(uri)
print(f" parsed: mime={mime!r} data len={len(back)}")
print("\n--- PEM wrap ---")
fake_der = secrets.token_bytes(64)
pem = pem_wrap(fake_der, "CERTIFICATE")
print(pem[:120] + "...")
print("\n--- overhead comparison ---")
raw = secrets.token_bytes(100)
print(f" raw: {len(raw)} bytes")
print(f" b64: {len(encode(raw))} chars ({len(encode(raw))/len(raw)*100:.0f}%)")
print(f" b85: {len(b85_encode(raw))} chars ({len(b85_encode(raw))/len(raw)*100:.0f}%)")
print(f" hex: {len(hex_encode(raw))} chars ({len(hex_encode(raw))/len(raw)*100:.0f}%)")
print("\n=== done ===")
For the binascii alternative — binascii is the lower-level C module underlying base64; it exposes binascii.hexlify(data) (→ lowercase hex bytes), binascii.unhexlify(hex_str), and binascii.crc32(data) directly without the higher-level wrappers; base64 provides named, intent-revealing functions — use binascii when you need raw hex conversion with minimal import overhead or CRC32 alongside encoding in the same module, base64 for all standard-compliant base64/base32/base85 encoding and decoding. For the itsdangerous alternative — itsdangerous (PyPI) combines base64url encoding with HMAC signing to produce tamper-proof signed tokens: URLSafeTimedSerializer(secret).dumps({"user_id": 1}) → a signed, time-limited string; stdlib base64 only encodes bytes with no authentication — use itsdangerous for email confirmation tokens, password reset links, and cookie values that must be tamper-evident, stdlib base64 for pure encoding tasks where authentication is handled separately (e.g., JWT libraries). The Claude Skills 360 bundle includes base64 skill sets covering encode()/decode()/decode_safe()/is_valid_base64() standard helpers, urlsafe_encode()/urlsafe_decode()/jwt_base64url_encode()/jwt_base64url_decode() URL-safe helpers, hex_encode()/b32_encode()/b85_encode() multi-alphabet converters, to_data_uri()/file_to_data_uri()/from_data_uri() data URI utilities, and mime_encode()/pem_wrap() MIME/PEM formatters. Start with the free tier to try binary encoding and base64 pipeline code generation.