Кодирование Base64 на Python: b64encode и примеры

·Backend Developer·ПровереноPriya Sharma·Опубликовано

Используйте бесплатный Base64 Encode Online прямо в браузере — установка не требуется.

Попробовать Base64 Encode Online онлайн →

Когда вы создаёте Python-сервисы, которые передают учётные данные в заголовках HTTP Basic Auth, встраивают бинарные ресурсы в ответы API или хранят TLS-сертификаты в переменных окружения, вам регулярно приходится писать код для Base64-кодирования на Python. Python поставляет модуль base64 в стандартной библиотеке — pip install не нужен — но различие между байтами и строками, а также разница между b64encode, urlsafe_b64encode и encodebytes вызывает путаницу у разработчиков чаще, чем можно было бы ожидать. Для быстрого кодирования без написания кода Base64 Encoder от ToolDeck справляется мгновенно прямо в браузере. Это руководство охватывает полный stdlib API, URL-безопасное кодирование для JWT, сценарии с файлами и ответами API, CLI-команды, высокопроизводительную альтернативу и четыре ошибки, которые я чаще всего встречаю при code review.

  • base64.b64encode() принимает bytes, а не str — всегда вызывайте .encode("utf-8") на входной строке перед передачей
  • Возвращаемое значение тоже bytes — вызовите .decode("utf-8") или .decode("ascii"), чтобы получить обычную str для встраивания в JSON или HTTP-заголовки
  • base64.urlsafe_b64encode() заменяет + → - и / → _, но сохраняет паддинг = — вручную удалите его через .rstrip("=") для JWT-сегментов
  • base64.encodebytes() вставляет \n каждые 76 символов (формат MIME) — никогда не используйте его для data URI, JSON-полей или переменных окружения
  • pybase64 (расширение на C, совместимый API) кодирует в 2–10× быстрее stdlib; оправдан для высоконагруженных сервисов с большими данными

Что такое Base64-кодирование?

Base64 преобразует произвольные бинарные данные в строку из 64 печатных ASCII-символов: A–Z, a–z, 0–9, + и /. Каждые 3 входных байта отображаются ровно в 4 символа Base64. Если длина входа не кратна 3, добавляются один или два символа = паддинга. Закодированный вывод всегда примерно на 33% больше оригинала.

Base64 — это не шифрование: он не обеспечивает никакой конфиденциальности. Его назначение — безопасность транспорта: многие протоколы и системы хранения разработаны для 7-битного ASCII-текста и не могут безопасно передавать произвольные бинарные байты. Base64 устраняет этот разрыв. Типичные применения в Python: заголовки HTTP Basic Auth, data URI для встраивания изображений в HTML или CSS, сегменты JWT-токенов, вложения MIME-почты и передача бинарных данных через переменные окружения или JSON API.

Before · text
After · text
deploy-svc:sk-prod-9f2a1c3e8b4d
ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

base64.b64encode() — Руководство по стандартному кодированию с примерами

base64.b64encode(s, altchars=None) — основная функция кодирования в stdlib Python. Она находится в модуле base64, который поставляется с каждой установкой Python. Функция принимает объект bytes и возвращает объект bytes, содержащий ASCII-представление Base64. В этом руководстве предполагается использование Python 3.x (3.6+).

Минимальный рабочий пример

Python 3.6+
import base64

# Кодирование пары учётных данных API для заголовка HTTP Basic Auth
service_id = "deploy-svc"
api_key    = "sk-prod-9f2a1c3e8b4d"

credential_bytes   = f"{service_id}:{api_key}".encode("utf-8")
encoded_bytes      = base64.b64encode(credential_bytes)
encoded_str        = encoded_bytes.decode("ascii")  # bytes → str

print(encoded_str)
# ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

import urllib.request

req = urllib.request.Request("https://api.internal/v1/deployments")
req.add_header("Authorization", f"Basic {encoded_str}")
# Значение заголовка: Basic ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

Расширенный пример — sort_keys, вложенные объекты, round-trip декодирование

Python 3.6+
import base64
import json

# Кодирование структурированной конфигурации сервера для переменной окружения
server_config = {
    "host":           "db-primary.eu-west-1.internal",
    "port":           5432,
    "database":       "analytics_prod",
    "max_connections": 150,
    "ssl": {
        "mode":          "verify-full",
        "cert_path":     "/etc/ssl/certs/db-client.crt",
        "reject_self_signed": True,
    },
}

config_json    = json.dumps(server_config, sort_keys=True)
encoded_bytes  = base64.b64encode(config_json.encode("utf-8"))
encoded_str    = encoded_bytes.decode("ascii")

print(encoded_str[:60] + "...")
# eyJkYXRhYmFzZSI6ICJhbmFseXRpY3NfcHJvZCIsICJob3N0IjogImRi...

# Декодирование и round-trip проверка
decoded_json   = base64.b64decode(encoded_str).decode("utf-8")
restored       = json.loads(decoded_json)

print(restored["host"])            # db-primary.eu-west-1.internal
print(restored["ssl"]["mode"])     # verify-full
Примечание:b64decode() по умолчанию снисходителен — он молча игнорирует недопустимые символы, включая пробелы и переносы строк. Передайте validate=True, чтобы вызвать binascii.Error при наличии любого символа, не входящего в Base64. Используйте это при декодировании недоверенных данных из внешних систем.

Кодирование не-ASCII и Unicode строк в Python

Строки Python 3 по умолчанию являются Unicode. Модуль base64 работает с bytes, а не со str — поэтому необходимо сначала закодировать строку в байты. Выбор кодировки важен: UTF-8 обрабатывает каждую кодовую точку Unicode и является правильным значением по умолчанию почти для всех случаев.

Python 3.6+
import base64

# Кодирование многоязычного контента — отображаемые имена пользователей международной платформы
user_names = [
    "Алексей Иванов",       # Кириллица — U+0410 и выше (основной пример)
    "田中太郎",              # Иероглифы CJK — 3 байта каждый в UTF-8
    "Carlos Mendoza",        # ASCII — 1 байт на символ
    "Мария Соколова",        # Кириллица — ещё один пример
]

for name in user_names:
    encoded = base64.b64encode(name.encode("utf-8")).decode("ascii")
    decoded = base64.b64decode(encoded).decode("utf-8")

    print(f"Оригинал : {name}")
    print(f"Кодировано: {encoded}")
    print(f"Туда-обратно: {decoded}")
    print(f"Совпадение: {name == decoded}")
    print()

# Оригинал : Алексей Иванов
# Кодировано: 0JDQu9C10LrRgdC10Lkg0JjQstCw0L3QvtCy
# Туда-обратно: Алексей Иванов
# Совпадение: True
Примечание:Если нужно убедиться в правильности кодирования конкретной строки, вставьте вывод Base64 прямо в Base64 Encoder от ToolDeck — он декодирует в реальном времени и показывает точное UTF-8 байтовое представление. Удобно при отладке кириллических, CJK или emoji-строк в данных.

Модуль base64 — Справочник функций

Модуль base64 предоставляет несколько функций кодирования. Вот полный справочник по тем, с которыми вы встретитесь на практике:

ФункцияВходВозвращаетОписание
b64encode(s, altchars=None)bytesbytesСтандартный Base64 (RFC 4648 §4). altchars заменяет символы + и / двумя пользовательскими байтами.
b64decode(s, altchars=None, validate=False)bytes | strbytesДекодирует стандартный Base64. validate=True вызывает binascii.Error при недопустимых символах.
urlsafe_b64encode(s)bytesbytesURL-безопасный Base64 (RFC 4648 §5). Использует - и _ вместо + и /. Сохраняет паддинг =.
urlsafe_b64decode(s)bytes | strbytesДекодирует URL-безопасный Base64. Принимает как дополненный, так и недополненный ввод.
encodebytes(s)bytesbytesMIME Base64: вставляет \n каждые 76 символов и добавляет завершающий \n. Только для email/MIME.
decodebytes(s)bytesbytesДекодирует MIME Base64. Игнорирует пробельные символы и встроенные переносы строк.
b16encode(s)bytesbytesHex-кодирование (Base16). Каждый байт становится двумя символами верхнего регистра hex. Без паддинга.
b32encode(s)bytesbytesBase32-кодирование. Использует A–Z и 2–7. Больший вывод, чем Base64; используется в TOTP-секретах.

Параметр altchars в b64encode принимает 2-байтовый объект, заменяющий символы + и /. Передача altchars=b'-_' даёт вывод, идентичный urlsafe_b64encode, но позволяет управлять паддингом отдельно.

URL-безопасный Base64 — urlsafe_b64encode() для JWT и параметров запроса

Стандартный Base64 использует + и / — оба являются зарезервированными символами в URL. Символ + в строке запроса декодируется как пробел, а / является разделителем пути. Когда закодированное значение появляется в URL, имени файла или cookie, нужен URL-безопасный вариант: urlsafe_b64encode() заменяет - на + и _ на /.

JWT используют URL-безопасный Base64 без паддинга для всех трёх сегментов (заголовок, данные, подпись). Паддинг нужно удалять вручную — stdlib Python его сохраняет.

Кодирование сегмента JWT-данных

Python 3.6+
import base64
import json

def encode_jwt_segment(data: dict) -> str:
    """Кодирует dict в URL-безопасную строку Base64 без паддинга (формат JWT)."""
    json_bytes = json.dumps(data, separators=(",", ":")).encode("utf-8")
    return base64.urlsafe_b64encode(json_bytes).rstrip(b"=").decode("ascii")

def decode_jwt_segment(segment: str) -> dict:
    """Декодирует URL-безопасный JWT-сегмент Base64 (обрабатывает отсутствующий паддинг)."""
    # Восстанавливаем паддинг: Base64 требует длину, кратную 4
    padding  = 4 - len(segment) % 4
    padded   = segment + ("=" * (padding % 4))
    raw      = base64.urlsafe_b64decode(padded)
    return json.loads(raw)

# Создаём заголовок и данные JWT
header  = {"alg": "HS256", "typ": "JWT"}
payload = {
    "sub":       "usr_7c3a9f1b2d",
    "workspace": "ws_eu-west-1-prod",
    "role":      "data-engineer",
    "iat":       1741824000,
    "exp":       1741910400,
}

header_segment  = encode_jwt_segment(header)
payload_segment = encode_jwt_segment(payload)

print(header_segment)
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

print(payload_segment)
# eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsIndvcmtzcGFjZSI6IndzX2...

# Проверяем round-trip
restored = decode_jwt_segment(payload_segment)
print(restored["role"])  # data-engineer
Примечание:urlsafe_b64decode() принимает как дополненный, так и недополненный ввод начиная с Python 3.x, но только если символы являются URL-безопасными (- и _). Никогда не передавайте стандартную строку Base64 (с + или /) в urlsafe_b64decode — несовпадающие символы вызовут скрытое повреждение данных или binascii.Error.

Кодирование файлов и ответов API в Python

В production-коде Base64-кодирование чаще всего применяется к файлам, которые нужно передать, и к ответам внешних API с бинарным содержимым. Оба сценария требуют тщательной обработки границы bytes.

Чтение файла с диска и его кодирование

Python 3.6+
import base64
import json
from pathlib import Path

def encode_file_to_base64(file_path: str) -> str:
    """Читает бинарный файл и возвращает его Base64-представление."""
    try:
        raw_bytes = Path(file_path).read_bytes()
        return base64.b64encode(raw_bytes).decode("ascii")
    except FileNotFoundError:
        raise FileNotFoundError(f"Файл не найден: {file_path}")
    except PermissionError:
        raise PermissionError(f"Доступ запрещён при чтении: {file_path}")

# Прикрепляем TLS-сертификат к манифесту деплоя
cert_b64 = encode_file_to_base64("./ssl/service-client.crt")

deployment_manifest = {
    "service":     "payment-processor",
    "environment": "production",
    "region":      "eu-west-1",
    "tls": {
        "client_cert":     cert_b64,
        "cert_format":     "base64-pem",
    },
}

# Записываем манифест — сертификат безопасно встроен как строка
with open("./dist/deployment-manifest.json", "w") as f:
    json.dump(deployment_manifest, f, indent=2)

print(f"Сертификат закодирован: {len(cert_b64)} символов")

Кодирование HTTP API-ответа для отладки

Python 3.6+
import base64
import requests  # pip install requests

def fetch_and_encode_binary(url: str, headers: dict | None = None) -> str:
    """Загружает бинарный ресурс из API и возвращает его в виде Base64."""
    response = requests.get(url, headers=headers or {}, timeout=10)
    response.raise_for_status()  # вызывает HTTPError для 4xx/5xx

    content_type = response.headers.get("Content-Type", "unknown")
    encoded      = base64.b64encode(response.content).decode("ascii")

    print(f"Content-Type : {content_type}")
    print(f"Размер raw   : {len(response.content):,} байт")
    print(f"Размер encoded: {len(encoded):,} символов")
    return encoded

# Пример: загружаем подписанный PDF-счёт из внутреннего API биллинга
invoice_b64 = fetch_and_encode_binary(
    "https://billing.internal/api/v2/invoices/INV-2026-0042/pdf",
    headers={"Authorization": "Bearer eyJhbGc..."},
)

# Прикрепляем к уведомлению
notification = {
    "recipient_id":  "team-finance",
    "invoice_id":    "INV-2026-0042",
    "attachment": {
        "filename":     "invoice-2026-0042.pdf",
        "content":      invoice_b64,
        "content_type": "application/pdf",
        "encoding":     "base64",
    },
}
print(f"Payload готов: {len(str(notification)):,} символов")

Как закодировать файл изображения в Base64 на Python

Кодирование изображения в Base64 и встраивание его в виде data URI — стандартный подход для HTML-шаблонов email, генерации PDF и самодостаточных HTML-снимков. Браузер интерпретирует закодированную строку напрямую — отдельный запрос изображения не нужен. Тот же шаблон работает для любого бинарного формата: PNG, JPEG, SVG, WebP или PDF.

Python 3.6+
import base64
import mimetypes
from pathlib import Path

def image_to_data_uri(image_path: str) -> str:
    """Преобразует файл изображения в data URI Base64 для встраивания в HTML."""
    path      = Path(image_path)
    mime_type = mimetypes.guess_type(image_path)[0] or "image/octet-stream"
    raw_bytes = path.read_bytes()
    encoded   = base64.b64encode(raw_bytes).decode("ascii")
    return f"data:{mime_type};base64,{encoded}"

# Встраиваем изображения продуктов в HTML-шаблон email
hero_uri      = image_to_data_uri("./assets/product-hero-768px.png")
thumbnail_uri = image_to_data_uri("./assets/product-thumb-128px.webp")

html_fragment = f"""
<img src="{hero_uri}"
     alt="Product hero"
     width="768" height="432"
     style="display:block;max-width:100%" />
"""

print(f"PNG data URI начинается с: {hero_uri[:60]}...")
# data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwAAAAA...
Примечание:Для SVG-файлов data URI с URL-кодированием (data:image/svg+xml,{encoded}) часто меньше, чем Base64, потому что SVG текстовый и Base64 увеличивает размер на ~33%. Используйте Base64 для растровых форматов (PNG, JPEG, WebP) и URL-кодирование для SVG.

Работа с большими файлами — кодирование Base64 по чанкам

Загрузка целого файла в память через Path.read_bytes() нормальна для файлов до ~50 МБ. При превышении этого порога пиковое потребление памяти становится значительным — файл 200 МБ требует ~200 МБ для исходных байтов плюс ~267 МБ для вывода Base64, всего ~467 МБ в одном процессе. Для больших файлов читайте и кодируйте по чанкам.

Критическое ограничение: размер чанка должен быть кратен 3 байтам. Base64 кодирует 3 входных байта ровно в 4 выходных символа. Если граница чанка приходится на некратное 3 место, кодировщик добавляет паддинг = посередине потока, делая конкатенированный вывод недействительным.

Потоковое кодирование в файл (без загрузки всего файла в память)

Python 3.6+
import base64
from pathlib import Path

CHUNK_SIZE = 3 * 1024 * 256  # 786 432 байта — кратно 3, ~768 КБ на чанк

def encode_large_file(input_path: str, output_path: str) -> int:
    """
    Кодирует большой бинарный файл в Base64 без полной загрузки в память.
    Возвращает количество записанных символов Base64.
    """
    total_chars = 0
    with open(input_path, "rb") as src, open(output_path, "w") as dst:
        while True:
            chunk = src.read(CHUNK_SIZE)
            if not chunk:
                break
            encoded_chunk = base64.b64encode(chunk).decode("ascii")
            dst.write(encoded_chunk)
            total_chars += len(encoded_chunk)
    return total_chars

# Кодируем 300 МБ видео продукта для манифеста доставки ресурсов
chars_written = encode_large_file(
    "./uploads/product-demo-4k.mp4",
    "./dist/product-demo-4k.b64",
)
print(f"Закодировано: {chars_written:,} символов Base64")
# Закодировано: 407 374 184 символа Base64

Кодирование директории бинарных ресурсов (вывод NDJSON)

Python 3.6+
import base64
import json
from pathlib import Path

def encode_assets_to_ndjson(asset_dir: str, output_path: str) -> int:
    """
    Кодирует все бинарные файлы в директории в NDJSON-манифест.
    Каждая строка — JSON-объект: {"path": "...", "mime": "...", "data": "<base64>"}
    Возвращает количество обработанных файлов.
    """
    import mimetypes

    asset_path = Path(asset_dir)
    count = 0

    with open(output_path, "w") as out:
        for file_path in sorted(asset_path.rglob("*")):
            if not file_path.is_file():
                continue
            mime = mimetypes.guess_type(str(file_path))[0] or "application/octet-stream"
            encoded = base64.b64encode(file_path.read_bytes()).decode("ascii")
            record  = {"path": str(file_path.relative_to(asset_path)), "mime": mime, "data": encoded}
            out.write(json.dumps(record) + "\n")
            count += 1

    return count

processed = encode_assets_to_ndjson("./dist/static/", "./dist/asset-bundle.ndjson")
print(f"Закодировано {processed} файлов в NDJSON-пакет ресурсов")
Примечание:Переходите от read_bytes() к чтению по чанкам, когда входной файл превышает ~50–100 МБ или когда ваш сервис обрабатывает много файлов одновременно и нагрузка по памяти становится критичной. Для файлов до 50 МБ однострочник b64encode(path.read_bytes()).decode() быстрее и проще в понимании.

Base64-кодирование в командной строке с помощью Python

Python поставляет CLI-интерфейс для модуля base64 — дополнительные инструменты не нужны. Он работает кроссплатформенно, что делает его полезным в CI-пайплайнах и Windows-окружениях, где системная команда base64 может быть недоступна.

bash
# ── python -m base64 ───────────────────────────────────────────────────
# Кодирование строки (stdin через pipe)
echo -n "deploy-svc:sk-prod-9f2a1c3e8b4d" | python3 -m base64
# ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

# Кодирование файла
python3 -m base64 ./ssl/service-client.crt

# Декодирование строки Base64
echo "ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==" | python3 -m base64 -d

# Декодирование файла Base64 обратно в бинарный
python3 -m base64 -d ./dist/service-client.b64 > ./restored.crt

# ── Однострочник Python — кроссплатформенно, работает на Windows ────────────────
# Кодирование строки
python3 -c "import base64,sys; print(base64.b64encode(sys.argv[1].encode()).decode())" "my-secret"
# bXktc2VjcmV0

# URL-safe кодирование (без паддинга)
python3 -c "import base64,sys; print(base64.urlsafe_b64encode(sys.argv[1].encode()).rstrip(b'=').decode())" "my-secret"
# bXktc2VjcmV0

# Кодирование файла в строку (результат на stdout)
python3 -c "import base64,sys; print(base64.b64encode(open(sys.argv[1],'rb').read()).decode())" ./config.json
Примечание:В отличие от системной команды base64 в macOS, python -m base64 по умолчанию не переносит вывод на 76 символах. Вывод — одна непрерывная строка, что и нужно для переменных окружения, JSON-полей и HTTP-заголовков. Используйте как замену системному base64 на любой ОС.

Высокопроизводительная альтернатива: pybase64

Модуль base64 из stdlib Python реализован на чистом Python (с тонким слоем C в CPython). Для сервисов, которые кодируют большие данные с высокой пропускной способностью — пайплайны обработки изображений, задачи массового экспорта, приём телеметрии в реальном времени — pybase64 является совместимой заменой, основанной на libbase64 — SIMD-ускоренной библиотеке C. Тесты производительности показывают улучшение пропускной способности в 2–10× в зависимости от размера данных и архитектуры CPU.

bash
pip install pybase64
Python 3.6+
import pybase64
import time

# pybase64 — замена stdlib: те же сигнатуры функций
sample_payload = b"x" * (1024 * 1024)  # 1 МБ бинарных данных

# Стандартное кодирование — идентичный вывод base64.b64encode()
encoded = pybase64.b64encode(sample_payload)
decoded = pybase64.b64decode(encoded)
assert decoded == sample_payload

# URL-safe кодирование — идентичный вывод base64.urlsafe_b64encode()
url_safe = pybase64.urlsafe_b64encode(sample_payload)

# b64encode_as_string() возвращает str напрямую — вызов .decode() не нужен
telemetry_event = b'{"event":"page_view","session_id":"sess_3a7f91c2","ts":1741824000}'
encoded_str: str = pybase64.b64encode_as_string(telemetry_event)

print(encoded_str[:48] + "...")
# eyJldmVudCI6InBhZ2VfdmlldyIsInNlc3Npb25faWQi...

# Сравнение пропускной способности (приблизительно, зависит от железа)
# stdlib  base64.b64encode(1 МБ):   ~80 МБ/с
# pybase64.b64encode(1 МБ):         ~800 МБ/с (путь SIMD на CPU с AVX2)

Переходите на pybase64, когда профилирование показывает Base64-кодирование как узкое место, или когда вы многократно кодируете данные объёмом более ~100 КБ. Для одноразового кодирования небольших строк (учётные данные, токены) stdlib достаточно быстр и не требует зависимостей.

Вывод в терминал с подсветкой синтаксиса

При отладке Base64-закодированных данных в терминале — особенно JSON-конфигураций или содержимого JWT — библиотека rich даёт подсвеченный синтаксис с отступами, который намного удобнее для чтения, чем сырой дамп. Особенно полезна в CLI-инструментах, отладочных скриптах и сессиях REPL.

bash
pip install rich
Python 3.6+
import base64
import json
from rich import print as rprint
from rich.syntax import Syntax
from rich.console import Console

console = Console()

def decode_and_pretty_print(encoded: str, label: str = "Декодированные данные") -> None:
    """Декодирует строку Base64, разбирает как JSON и выводит с подсветкой синтаксиса."""
    raw_bytes = base64.b64decode(encoded + "==")  # допустимый паддинг
    try:
        parsed  = json.loads(raw_bytes)
        pretty  = json.dumps(parsed, indent=2, ensure_ascii=False)
        syntax  = Syntax(pretty, "json", theme="monokai", line_numbers=False)
        console.rule(f"[bold blue]{label}")
        console.print(syntax)
    except json.JSONDecodeError:
        # Не JSON — выводим сырой текст
        console.rule(f"[bold yellow]{label} (сырой текст)")
        rprint(raw_bytes.decode("utf-8", errors="replace"))

# Инспектируем сегмент JWT-данных из неудачного запроса аутентификации
jwt_payload_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJkYXRhLWVuZ2luZWVyIiwiZXhwIjoxNzQxOTEwNDAwfQ"
decode_and_pretty_print(jwt_payload_segment, "JWT Payload")
Примечание:Используйте вывод rich только для отображения в терминале — при отладке, логировании в stdout или интерактивных CLI-инструментах. Никогда не используйте его для записи Base64 в файлы, возврата из API-эндпоинтов или хранения в переменных окружения, так как rich добавляет ANSI-escape-коды, которые портят данные.

Типичные ошибки

Я просмотрел много Python-кодовых баз с Base64-кодированием, и эти четыре ошибки встречаются регулярно — часто остаются незамеченными до тех пор, пока не-ASCII ввод или бинарный файл не попадёт на путь кодирования в production.

Ошибка 1 — Передача str вместо bytes в b64encode()

Проблема: b64encode() ожидает объект bytes. Передача str немедленно вызывает TypeError: a bytes-like object is required. Решение: всегда вызывайте .encode("utf-8") на строке перед кодированием.

Before · Python
After · Python
import base64

# ❌ TypeError: a bytes-like object is required, not 'str'
webhook_secret = "wh-secret-a3f91c2b4d"
encoded = base64.b64encode(webhook_secret)  # падает
import base64

# ✅ Сначала кодируем str в bytes
webhook_secret = "wh-secret-a3f91c2b4d"
encoded = base64.b64encode(webhook_secret.encode("utf-8"))
# b'd2gtc2VjcmV0LWEzZjkxYzJiNGQ='

Ошибка 2 — Забыть вызвать .decode() на результате bytes

Проблема: b64encode() возвращает bytes, а не str. Встраивание напрямую в f-строку даёт b'...' в выводе — недопустимое значение HTTP-заголовка, которое также ломает сериализацию JSON. Решение: всегда вызывайте .decode("ascii") на закодированном результате.

Before · Python
After · Python
import base64

credential = base64.b64encode(b"svc-monitor:sk-7f3a1b")
# ❌ Заголовок Authorization содержит "b'c3ZjLW1vbml0b3I6c2stN2YzYTFi'"
headers = {"Authorization": f"Basic {credential}"}
import base64

credential = base64.b64encode(b"svc-monitor:sk-7f3a1b").decode("ascii")
# ✅ Authorization: Basic c3ZjLW1vbml0b3I6c2stN2YzYTFi
headers = {"Authorization": f"Basic {credential}"}

Ошибка 3 — Использование encodebytes() вместо b64encode()

Проблема: encodebytes() вставляет \n каждые 76 символов (MIME-перенос строк) и добавляет завершающий перенос. Хранение этого в JSON-поле, переменной окружения или data URI встраивает буквальные символы переноса строки, которые портят значение далее по цепочке. Решение: используйте b64encode() везде, кроме составления MIME-почты.

Before · Python
After · Python
import base64, json

cert_bytes = open("./ssl/root-ca.crt", "rb").read()
# ❌ encodebytes() добавляет \n каждые 76 символов — ломает JSON и переменные окружения
cert_b64 = base64.encodebytes(cert_bytes).decode()
config   = json.dumps({"ca_cert": cert_b64})  # переносы строк внутри значения
import base64, json
from pathlib import Path

cert_bytes = Path("./ssl/root-ca.crt").read_bytes()
# ✅ b64encode() создаёт единую непрерывную строку
cert_b64 = base64.b64encode(cert_bytes).decode("ascii")
config   = json.dumps({"ca_cert": cert_b64})  # чистое однострочное значение

Ошибка 4 — Декодирование URL-safe Base64 стандартным декодером

Проблема: URL-safe Base64 использует - и _ вместо + и /. Передача URL-safe строки в b64decode() молча производит неверные байты для любого сегмента с этими символами — исключение по умолчанию не вызывается. Решение: используйте urlsafe_b64decode() для URL-safe ввода или передавайте validate=True для раннего обнаружения несоответствия.

Before · Python
After · Python
import base64

# ❌ JWT payload-сегмент использует URL-safe Base64 (- и _)
# b64decode() молча производит неверные байты для таких символов
jwt_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJhZG1pbiJ9"
wrong = base64.b64decode(jwt_segment)  # молча неверно при наличии - или _
import base64

# ✅ Используем urlsafe_b64decode() для JWT и URL-safe ввода
jwt_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJhZG1pbiJ9"
padding     = 4 - len(jwt_segment) % 4
raw         = base64.urlsafe_b64decode(jwt_segment + "=" * (padding % 4))
# b'{"sub":"usr_7c3a9f1b2d","role":"admin"}'

Методы Base64 в Python — Быстрое сравнение

МетодТипы входаURL-safe символыПаддингПереносы строкВозвращаетТребует установки
b64encode()bytes, bytearray, memoryview❌ + и /✅ паддинг =❌ нетbytesНет
urlsafe_b64encode()bytes, bytearray, memoryview✅ - и _✅ паддинг =❌ нетbytesНет
b64encode(altchars=b"-_")bytes, bytearray, memoryview✅ 2 пользовательских✅ паддинг =❌ нетbytesНет
encodebytes()bytes, bytearray, memoryview❌ + и /✅ паддинг =✅ \n каждые 76 символовbytesНет
pybase64.b64encode()bytes, bytearray, memoryview❌ + и /✅ паддинг =❌ нетbytespip install
pybase64.b64encode_as_string()bytes, bytearray, memoryview❌ + и /✅ паддинг =❌ нетstrpip install

Используйте b64encode() для подавляющего большинства случаев: HTTP-заголовки, JSON-поля, переменные окружения и data URI. Переходите на urlsafe_b64encode(), когда вывод будет присутствовать в URL, имени файла, cookie или JWT-сегменте. Используйте encodebytes() только при составлении MIME-вложений для email — перенос строк требуется спецификацией MIME, но молча сломает всё остальное. Обращайтесь к pybase64, когда кодируете данные объёмом более ~100 КБ в горячем пути.

Часто задаваемые вопросы

Почему base64.b64encode() возвращает bytes, а не строку?
Python 3 строго разделяет текст (str) и бинарные данные (bytes). base64.b64encode() работает с бинарными данными и возвращает бинарные данные — даже несмотря на то, что выходные символы являются печатаемым ASCII. Это намеренное решение: оно вынуждает явно определять границы кодировки. Чтобы получить str, вызовите .decode("ascii") или .decode("utf-8") на результате. Поскольку допустимый вывод Base64 содержит только ASCII-символы, обе кодировки дают идентичный результат.
В чём разница между b64encode() и encodebytes() в Python?
b64encode() создаёт единую непрерывную строку Base64 — правильный выбор для HTTP-заголовков, JSON-полей, data URI, переменных окружения и JWT-сегментов. encodebytes() (ранее encodestring() в Python 2) вставляет символ переноса строки каждые 76 байт и добавляет завершающий перенос. Это формат MIME-переноса строк, требуемый для вложений email согласно RFC 2045. Использование encodebytes() вне составления email встроит буквальные переносы строк в вывод, портя заголовки, JSON-строки и URL-значения.
Как закодировать в Base64 строку с не-ASCII символами в Python?
Вызовите .encode("utf-8") на строке, чтобы преобразовать её в bytes, затем передайте эти bytes в base64.b64encode(). Для декодирования выполните шаги в обратном порядке: base64.b64decode(encoded), затем .decode("utf-8") на результате. UTF-8 — правильный выбор почти для всего текста: он обрабатывает каждую кодовую точку Unicode, включая кириллицу, иероглифы CJK, арабский и emoji. Использование .encode("ascii") на не-ASCII тексте вызовет UnicodeEncodeError, что обычно является правильным поведением, так как выявляет несоответствие кодировки на ранней стадии.
Как закодировать файл в Base64 на Python?
Прочитайте файл в бинарном режиме, затем вызовите base64.b64encode() на байтах. Простейший однострочник: encoded = base64.b64encode(Path("file.bin").read_bytes()).decode("ascii"). Для больших файлов (более ~50–100 МБ) избегайте загрузки всего файла в память. Вместо этого читайте по чанкам размером, кратным 3 байтам (например, 3 × 1024 × 256 = 786 432 байта) и кодируйте каждый чанк отдельно — обработка чанков размером, кратным 3, предотвращает появление паддинга = посередине вывода.
Почему urlsafe_b64encode() в Python всё равно включает паддинг =? JWT его не использует.
Stdlib следует спецификации RFC 4648 §5, которая сохраняет паддинг =. JWT (RFC 7519) определяет собственное кодирование Base64url, полностью убирающее паддинг. Несоответствие является намеренным решением спецификации: паддинг RFC 4648 делает строку самодостаточной (всегда можно определить исходную длину в байтах), тогда как JWT убирает его для уменьшения длины токена. Для соответствия формату JWT вызовите .rstrip(b"=") на закодированном выводе перед декодированием с .decode("ascii"). При декодировании добавьте правильный паддинг: padding = 4 - len(segment) % 4; padded = segment + "=" * (padding % 4).
Можно ли проверить, является ли строка допустимым Base64 перед декодированием?
Передайте validate=True в base64.b64decode(). С этим флагом любой символ за пределами алфавита стандартного Base64 (A–Z, a–z, 0–9, +, /, =) вызывает binascii.Error. Без validate=True b64decode() молча игнорирует недопустимые символы, что может скрыть испорченный ввод. Для URL-safe Base64 параметра validate в urlsafe_b64decode() нет — можно проверить вручную с помощью regex: import re; bool(re.fullmatch(r"[A-Za-z0-9_-]+=*", segment)). Всегда проверяйте ввод из недоверенных внешних источников перед декодированием.

Связанные инструменты

Для кодирования или декодирования в один клик без написания Python-кода вставьте строку или файл прямо в Base64 Encoder — он обрабатывает стандартный и URL-safe режимы мгновенно в браузере без какой-либо настройки.

Также доступно на:JavaScriptJava
MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

PS
Priya SharmaТехнический рецензент

Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.