Когда API возвращает поле content вида eyJob3N0IjogImRiLXByb2Qi…, или менеджер секретов передаёт закодированные учётные данные, или нужно извлечь полезную нагрузку JWT — декодирование Base64 в Python — ваш первый инструмент. Встроенный модуль base64 справляется со всем этим, однако тонкости работы с bytes и строками, URL-безопасными алфавитами и отсутствующим паддингом ловят почти каждого разработчика хотя бы раз — я отлаживал эту категорию ошибок на код-ревью больше раз, чем хотелось бы признавать. Это руководство охватывает base64.b64decode(), urlsafe_b64decode(), автоматическое восстановление паддинга, декодирование из файлов и HTTP-ответов, CLI-инструменты, валидацию входных данных и четыре распространённые ошибки с примерами до/после — все примеры работают на Python 3.8+. Если нужно быстро декодировать строку без написания кода, Base64 Decoder от ToolDeck мгновенно обрабатывает стандартный и URL-безопасный Base64 прямо в браузере.
- ✓base64.b64decode(s) входит в стандартную библиотеку Python — установка не требуется; функция всегда возвращает bytes, а не str.
- ✓Чтобы преобразовать bytes в строку Python, вызовите .decode("utf-8") после b64decode() — функция не знает исходную кодировку текста.
- ✓Для URL-безопасного Base64 (использует - и _ вместо + и /), применяйте base64.urlsafe_b64decode() — стандарт для JWT, токенов OAuth и учётных данных Google API.
- ✓Исправьте распространённую ошибку "Incorrect padding" с помощью: padded = s + "=" * (-len(s) % 4) — добавляет 0, 1 или 2 символа по необходимости.
- ✓Используйте validate=True для любых внешних данных, чтобы 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() — декодирование через стандартную библиотеку
Модуль base64 в Python поставляется со стандартной библиотекой — ничего устанавливать не нужно, он всегда доступен. Основная функция — 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-токенах, PKCE-запросах OAuth 2.0, учётных данных Google Cloud и большинстве современных процессов веб-аутентификации.
Передача 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 символа паддинга по необходимости и является холостой операцией, когда строка уже правильно дополнена. Это идиоматическое Python-решение для проблем с паддингом в JWT и OAuth.Справочник параметров base64.b64decode()
Все параметры ниже применяются как к b64decode(), так и к urlsafe_b64decode(), за исключением altchars, который доступен только в b64decode().
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
| s | bytes | str | bytearray | — | Закодированный в Base64 входной поток для декодирования; ASCII str принимается наравне с байтовыми типами. |
| altchars | bytes | None | None | Последовательность из 2 байт, заменяющая + и /; позволяет использовать нестандартные алфавиты Base64, выходящие за рамки URL-безопасного варианта. |
| validate | bool | False | При значении True вызывает binascii.Error для любого символа за пределами алфавита Base64; при False байты не из алфавита (переносы строк, пробелы) молча игнорируются. |
Значение validate=False по умолчанию намеренно предусмотрено для PEM-форматированных данных и многострочного Base64 (где переносы строк часты). Для API-нагрузок, пользовательских загрузок или любых ненадёжных входных данных передавайте validate=True, чтобы поймать повреждённые или внедрённые данные на раннем этапе и получить понятное сообщение об ошибке.
Ошибка паддинга при декодировании Base64 в Python — как исправить
Самая частая ошибка при декодировании Base64 в Python:
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: URL-безопасное декодирование с паддингом для OAuth / JWT
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Декодирование Base64 из файла и API-ответа
Чтение 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")Декодирование Base64 из HTTP API-ответа
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))
"Для исследовательской работы, когда написание командного конвейера кажется излишним, вставьте строку в онлайн-декодер Base64 — он автоматически определяет URL-безопасный ввод и исправляет паддинг на лету.
Валидация входных данных Base64 перед декодированием
Когда данные Base64 поступают от пользовательского ввода, вебхука или ненадёжного стороннего 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
В подавляющем большинстве случаев модуль base64 из стандартной библиотеки Python вполне достаточен. Если вы обрабатываете тысячи API-нагрузок в секунду, декодируете многомегабайтные двоичные вложения в плотном цикле, или профилировщик показывает операции Base64 как узкое место — рассмотрите pybase64. Это обёртка на C над libbase64, обычно работающая в 2–5 раз быстрее реализации из stdlib на больших входных данных.
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: использование b64decode() для URL-безопасного Base64
# ❌ 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")Декодирование больших файлов Base64 в Python
Загрузка 200 МБ файла Base64 через Path.read_text() и декодирование его за один вызов одновременно выделит память для закодированной строки, декодированных байт и промежуточных представлений — что легко исчерпает память на ограниченных серверах или в Lambda-функциях. Для файлов размером более ~50–100 МБ используйте вместо этого потоковый подход.
Потоковое декодирование на диск (без загрузки всего файла в RAM)
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 с помощью 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() для PEM-сертификатов, MIME-вложений и любого Base64, оборачивающегося на фиксированной ширине строки. Используйте потоковый подход выше для больших непрозрачных блобов (бэкапы, медиафайлы). Для компактных однострочных токенов (JWT, OAuth) b64decode() или urlsafe_b64decode() всегда является правильным выбором.Методы декодирования Base64 в Python — быстрое сравнение
| Метод | Алфавит | Паддинг | Вывод | Требует установки | Лучше всего для |
|---|---|---|---|---|---|
| base64.b64decode() | Стандартный (A–Z a–z 0–9 +/) | Обязателен | bytes | Нет (stdlib) | Общего назначения, email, PEM |
| base64.decodebytes() | Стандартный (A–Z a–z 0–9 +/) | Игнорируется (убирает пробелы) | bytes | Нет (stdlib) | PEM-сертификаты, MIME-вложения, многострочный Base64 |
| base64.urlsafe_b64decode() | URL-безопасный (A–Z a–z 0–9 -_) | Обязателен | bytes | Нет (stdlib) | JWT, OAuth, Google Cloud API |
| base64.b32decode() | 32-символьный (A–Z, 2–7) | Обязателен | bytes | Нет (stdlib) | TOTP-секреты, DNS-совместимые ID |
| base64.b16decode() | Шестнадцатеричный (0–9, A–F) | Нет | bytes | Нет (stdlib) | Hex-закодированные контрольные суммы, хэши |
| pybase64.b64decode() | Стандартный (A–Z a–z 0–9 +/) | Обязателен | bytes | Да (pip) | Высоконагруженные конвейеры, большие нагрузки |
| CLI: base64 --decode | Стандартный | Авто | stdout | Нет (системный) | Быстрая проверка в терминале |
Используйте b64decode() по умолчанию. Переключайтесь на urlsafe_b64decode()как только увидите - или _ во входных данных — эти символы являются безошибочным признаком URL-безопасного Base64. Обращайтесь к pybase64 только после того, как профилирование подтвердит узкое место. Для разовых проверок в процессе разработки Base64 Decoder от ToolDeck обрабатывает оба алфавита и автоматически исправляет паддинг — Python-окружение не нужно.
Часто задаваемые вопросы
Как декодировать строку Base64 в обычную строку в Python?
Вызовите base64.b64decode(encoded), чтобы получить bytes, затем вызовите .decode("utf-8")на результате, чтобы получить Python str. Эти два шага всегда раздельны, потому что b64decode() только обращает алфавит Base64 — он не знает, было ли исходное содержимое UTF-8, Latin-1 или двоичным. Если данные используют не UTF-8 кодировку, передайте правильное имя кодека в .decode(), например .decode("latin-1").
Почему при декодировании Base64 в Python появляется ошибка “Incorrect padding”?
Строки Base64 должны иметь длину, кратную 4 символам. JWT, токены OAuth и данные, передаваемые в URL, часто удаляют завершающий символ паддинга =. Исправьте это, добавив "=" * (-len(s) % 4) перед декодированием. Эта формула добавляет ровно 0, 1 или 2 символа по необходимости и является безопасной холостой операцией, когда строка уже правильно дополнена.
В чём разница между b64decode() и urlsafe_b64decode() в Python?
Оба декодируют один и тот же алгоритм Base64, но с разными алфавитами для 62-го и 63-го символов.b64decode() использует + и /; urlsafe_b64decode() использует - и _. URL-безопасный вариант определён в RFC 4648 §5 и используется везде, где Base64 должен выживать в URL, HTTP-заголовках или значениях cookie без процентного кодирования. Путаница между ними приводит либо к binascii.Error, либо к незаметно повреждённому выводу.
Как декодировать изображение, закодированное в Base64, в Python?
Декодируйте в bytes с помощью base64.b64decode(encoded), затем запишите эти bytes непосредственно в файл — не вызывайте .decode("utf-8") на данных изображения. Если входные данные — это data 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")Можно ли декодировать Base64 в Python без импорта модулей?
Технически да, но нет никаких причин это делать. Модуль base64 входит в стандартную библиотеку Python, всегда доступен, всегда установлен — у него нет зависимостей, а его функции реализованы на C. Переписывать Base64 с нуля было бы медленнее, более подверженным ошибкам и сложнее в обслуживании. Всегда используйте import base64.
Как декодировать Base64 в Python, когда входные данные — bytes, а не строка?
base64.b64decode() принимает str, bytes и bytearray взаимозаменяемо — преобразование не требуется. Если вы получаете b"SGVsbG8=" из сокета или при чтении файла, передайте это напрямую. Восстановление паддинга работает так же с bytes: data + b"=" * (-len(data) % 4) при работе в режиме bytes.
Связанные инструменты
- Base64 Encode — мгновенно кодируйте текст или бинарные файлы в Base64; удобно для создания тестовых данных для вашего Python-кода декодирования без запуска скриптов.
- JWT Decoder — просматривайте заголовок и полезную нагрузку JWT без написания кода; нагрузка декодируется с помощью URL-безопасного Base64 под капотом, точно как показано в примерах выше.
- URL Decode — процентное декодирование строк запроса и сегментов пути; часто требуется вместе с декодированием Base64 при разборе URL обратных вызовов OAuth или нагрузок вебхуков.
- URL Encode — процентное кодирование специальных символов; удобно, когда нужно безопасно встроить значение, закодированное в Base64, внутрь параметра URL-запроса.