[СРАВНЕНИЕ] 10 мин чтения

[СРАВНЕНИЕ] Base64, Base64URL и Base32

Три кодирования, один RFC. Здесь разбирается, чем они отличаются на самом деле — алфавит, накладные расходы, читаемость, чувствительность к регистру — и как выбрать подходящее для URL, имён файлов, писем, QR-кодов и кодов, произносимых вслух.

Апрель 2026 | comparison

// БЫСТРАЯ ТАБЛИЦА СРАВНЕНИЯ

                 Base64          Base64URL        Base32
                 (RFC 4648 §4)   (RFC 4648 §5)    (RFC 4648 §6)
────────────────────────────────────────────────────────────────
Alphabet size    64              64               32
Bits per char    6               6                5
Characters used  A-Z a-z 0-9     A-Z a-z 0-9      A-Z 2-7
                 + /             - _              (+ = for pad)
Padding          = (required)    = (optional)     = (optional)
Case-sensitive   Yes             Yes              No (A = a)
Size overhead    ~33%            ~33%             ~60%
URL-safe         No              Yes              Yes
Filename-safe    No              Yes              Yes
DNS-safe         No              Yes              Yes
Human-readable   Medium          Medium           High
Human-spoken     Painful         Painful          Doable
QR-code friendly OK              OK               Excellent
                 (alphanumeric)  (alphanumeric)   (alphanumeric mode)

// ЧТО У НИХ ОБЩЕГО

Все три определены в RFC 4648 — едином документе 2006 года, объединившем семейство «двоично-в-текст кодирований base-N». У них общий базовый алгоритм: взять двоичный вход, перегруппировать биты в куски по log₂(размер алфавита), сопоставить каждому куску символ, дополнить паддингом до границы слова на выходе.

• Base64: куски по 6 бит → 4 символа на 3 байта (соотношение 4/3, ~33% сверху)
• Base32: куски по 5 бит → 8 символов на 5 байт (соотношение 8/5, ~60% сверху)
• Base16 (hex): куски по 4 бита → 2 символа на 1 байт (соотношение 2/1, 100% сверху)

Все три обратимы, детерминированы и сохраняют каждый байт входа. Это именно кодирования, а не сжатие и не шифрование. Любой, у кого есть строка, может её декодировать.

// КОГДА ВЫБИРАТЬ BASE64 (СТАНДАРТНЫЙ, §4)

Стандартный Base64 — дефолт для любого текстового канала, кроме URL. Тела MIME-писем, PEM-обёрнутые сертификаты, HTTP Basic Auth, S/MIME, XML-DSIG, data URI и большинство файловых форматов «бинарь-в-тексте» используют именно его. Символы + / = безопасны внутри атрибутов в кавычках, внутри заголовков писем (при переносе строк) и внутри строк XML/JSON.

Выбирайте стандартный Base64, когда нижестоящий потребитель — текстовый протокол, допускающий произвольный печатаемый ASCII, и особенно когда спецификация на уровне RFC прямо это требует (MIME: RFC 2045; PEM: RFC 7468; HTTP Basic Auth: RFC 7617; data URI: RFC 2397).

  • > Вложения электронной почты (MIME base64 transfer encoding)
  • > PEM-сертификаты, ключи, CRL (-----BEGIN ... -----)
  • > Значение заголовка HTTP Basic Authentication
  • > Data URI: data:image/png;base64,...
  • > S/MIME и XML-ENC полезные нагрузки
  • > Классические SOAP / XML-DSIG подписи
  • > Любое двоичное поле в JSON-документе, которое затем не помещается в URL

// КОГДА ВЫБИРАТЬ BASE64URL (§5)

Как только ваш вывод Base64 касается URL, значения cookie, имени файла, DNS-метки или любого места, где + / = пришлось бы процентно кодировать, переходите на Base64URL. Он использует тот же 64-символьный алфавит с двумя заменами (+ → -, / → _) и обычно отбрасывает паддинг.

  • > Токены JWT — заголовок, payload, подпись — всё это base64url (RFC 7515)
  • > OAuth 2.0 PKCE code_challenge (RFC 7636)
  • > Параметры state и nonce в OpenID Connect
  • > Магические ссылки, инвайт-токены, токены сброса пароля
  • > Значения cookie, которые могут попасть в URL
  • > Имена файлов, производные от хэшей — избегайте / в именах файлов
  • > DNS-метки, TXT-записи — дефисы допустимы, слэши нет
  • > Ключи content-addressable хранилищ
  • > Короткие URL-идентификаторы на основе случайных байт

// КОГДА ВЫБИРАТЬ BASE32 (§6)

Base32 использует всего 32 символа: заглавные A–Z и цифры 2–7. Это ~60% накладных расходов — гораздо хуже, чем у Base64, — но взамен вы получаете три очень специфических свойства, недостижимых для Base64.

Регистронезависимость. Алфавит состоит только из заглавных букв. Человек, читающий или вводящий строку, может игнорировать регистр; JBSWY3DP и jbswy3dp декодируются одинаково.

Нет визуально похожих символов. Цифры 0, 1, 8 и 9 исключены, потому что в типовых шрифтах они похожи на O, I, B и g. Используются только 2–7. Это радикально повышает надёжность ручного набора с печатной страницы или экрана телефона.

Совместимость с alphanumeric-режимом QR-кодов. У QR-кодов есть специальный «alphanumeric»-режим, который кодирует 5,5 бит на символ, используя подмножество ASCII. Base32 целиком укладывается в это подмножество (плюс паддинг), поэтому QR с Base32 получается заметно меньше, чем QR с Base64.

  • > Секреты TOTP / HOTP — Google Authenticator, 1Password, Authy используют Base32
  • > Tor .onion-адреса v3 — 56-символьные Base32-представления ключей ed25519
  • > BitTorrent info-hash в magnet-ссылках
  • > Коды местоположения типа geohash, которыми делятся люди
  • > Лицензионные ключи и серийные номера продуктов
  • > Печатаемые восстановительные коды (резервные 2FA-коды, мнемоники кошельков)
  • > Передача вроде DTMF через голосовые каналы
  • > Системы, которым нужно регистронезависимое хранение (DNS-метки)

// НАКЛАДНЫЕ РАСХОДЫ — КОНКРЕТНЫЙ ПРИМЕР

// Input: a 32-byte SHA-256 hash
// Raw: 0x89abcdef…                             (32 bytes, binary — can't put in text)
// Hex (Base16): 40b2e2…                        (64 chars, 100% overhead)
// Base32:       5ENM4H2TQWMZ3O4OQBJAFY5Q       (56 chars, 75% overhead)
// Base64:       ia+N7/eZtRsPj5TqFoqUlD…        (44 chars, 37% overhead)
// Base64URL:    ia-N7_eZtRsPj5TqFoqUlD…        (43 chars, 34% overhead, no padding)

// Input: a 16-byte UUID
// Hex:       e7a6c1d0-4b7d-4c6c-8e2f-9f1a3e4b5c6d (36 chars incl. dashes)
// Base32:    5WTMDUCLPVGGZDRPTF…                  (26 chars)
// Base64:    56bB0Et9TGyOL58aPktcbQ==             (24 chars)
// Base64URL: 56bB0Et9TGyOL58aPktcbQ               (22 chars, no padding)

// БЕНЧМАРК ПО УДОБОЧИТАЕМОСТИ

Именно здесь Base32 блистает. Попробуйте прочитать вслух:

a+b/c1D2e3F/+g= — Base64. «маленькая-a, плюс, маленькая-b, слэш-вперёд, маленькая-c, один, большая-D, два, маленькая-e, три, большая-F, слэш-вперёд, плюс, маленькая-g, равно». Один регистр уже провоцирует ошибки ввода.

JBSWY3DPEHPK3PXP — Base32. «J-B-S-W-Y, три, D-P-E-H-P-K, три, P-X-P». Регистр не важен. Нет путаницы 0/O или 1/l. Такое можно надиктовать по телефону с высокой надёжностью.

Именно поэтому TOTP использует Base32: кому-то приходится вводить секрет в приложение-аутентификатор с резервного экрана QR-кода. Регистрозависимость Base64 породила бы бесконечный поток обращений в поддержку.

// СРАВНЕНИЕ ПО РАЗМЕРУ QR-КОДА

У QR-кодов есть специальный «alphanumeric mode», упаковывающий 5,5 бит на символ из подмножества в 45 знаков: 0–9, A–Z (только верхний регистр), пробел и $ % * + - . / :. Всё, что выходит за пределы этого подмножества, переводит QR-код в «byte mode», где на символ уходит 8 бит — и QR заметно разрастается.

Base32 полностью укладывается в alphanumeric-подмножество. Base64 — нет: строчные буквы и +/= вынуждают переход в byte mode (формально +/ входят в alphanumeric, но любые строчные буквы уже переводят в byte mode). В итоге одна и та же полезная нагрузка помещается в меньший QR, если закодирована в Base32 — часто это разница между читабельным 21×21 и перегруженным 33×33 QR-кодом.

// ПОДВОДНЫЕ КАМНИ ДЕКОДИРОВАНИЯ

  • > Регистр — декодеры Base64 отвергают вход с неправильным регистром (SGVsbG8=sgvSbg8=). Декодеры Base32 обычно нормализуют в верхний регистр перед поиском, поэтому терпимы к любому.
  • > Паддинг — стандартный Base64 требует паддинг =; JWT/base64url запрещает его; в Base32 он опционален (RFC 4648 §6). Всегда проверяйте, что ожидает ваш декодер.
  • > Пробельные символы — MIME Base64 переносится по 76 колонкам с CR-LF. Часть декодеров терпит пробелы, часть — нет. Срезайте их перед atob() и его аналогами.
  • > Коллизии алфавитов — подача Base64 в Base32-декодер (или наоборот) поначалу может казаться рабочей — A, B, C валидны в обоих — а затем тихо рушится на + или =.
  • > Crockford Base32 — это не-RFC-вариант, используемый в ID Stripe и некоторых блокчейнах. У него другой алфавит (без I, L, O, U) и поддержка контрольных знаков. Не путайте с RFC 4648 Base32.
  • > Base32 Extended Hex (RFC 4648 §7) — альтернативный алфавит Base32, сохраняющий лексикографический порядок сортировки. Используется в DNSSEC NSEC3. Его легко перепутать со стандартным Base32.

// БЛОК-СХЕМА ПРИНЯТИЯ РЕШЕНИЯ

Does the output go into a URL, cookie, filename, DNS, JWT, or OAuth flow?
│
├─ Yes  →  Does a human need to type or speak the string?
│         │
│         ├─ Yes  →  Base32 (uppercase, no ambiguous chars)
│         │         e.g., TOTP seeds, recovery codes
│         │
│         └─ No   →  Base64URL (more compact, URL-safe)
│                   e.g., JWT, short tokens, hash-named files
│
└─ No  →  Does the output go into a QR code that must stay tiny?
          │
          ├─ Yes  →  Base32 (fits in QR alphanumeric mode)
          │
          └─ No   →  Standard Base64
                    e.g., email MIME, PEM, HTTP Basic, data URI

// ПОЧЕМУ НЕ BASE16 (HEX)?

Шестнадцатеричный (в RFC 4648 §8 именно это и называется Base16) — универсальный запасной вариант. Каждая shell-утилита, отладчик и протокол его понимают. Он регистронезависим, элементарно читается человеком и тривиально реализуется. Но он удваивает размер полезной нагрузки (100% сверху), поэтому применяется только для маленьких идентификаторов фиксированной длины: SHA-256-хэшей (64 hex-символа = 32 байта), UUID (32 hex-символа = 16 байт), MAC-адресов, адресов памяти в отладчиках.

Для всего, что больше нескольких десятков байт, накладные расходы hex в сети по-настоящему болезненны. Base64 на 50% меньше hex, Base32 — на 25%. Именно поэтому Base64 победил в почте и веб-встраиваниях, а hex остался в отладке и отображении хэшей.

// А КАК НАСЧЁТ BASE58 / BASE62 / BASE85?

Не-RFC-кодирования base-N существуют под конкретные ниши:
Base58 — адреса Bitcoin, ID фото Flickr. Исключает четыре неоднозначных символа (0, O, I, l) и +/ для удобства ручного набора. ~37% сверху.
Base62 — сокращатели URL, ID-снежинки Twitter. Использует только буквы и цифры (без спецзнаков), безопасен в URL без экранирования. ~34% сверху.
Base85 / Ascii85 / Z85 — PostScript, PDF, старые кадры ZeroMQ. ~25% сверху (плотнее, чем Base64), но с хитрыми символами, провоцирующими ад экранирования в XML/JSON.

Они интересны, но не стандартизованы в RFC 4648. Если вы делаете открытый протокол, Base64 или Base64URL почти всегда безопаснее по умолчанию — стандартная библиотека любого языка уже их поддерживает. Выберете Base58 — будете тащить зависимость каждому потребителю.

// ПОПРОБУЙТЕ ИХ БОК О БОК

Кодировщик Base64 — стандартный алфавит с переключателем URL-safe
Кодировщик Base64URL — URL-safe со снятым паддингом
Кодировщик Base32 — алфавит из RFC 4648 §6
Кодировщик Base16 (hex) — для сравнения
Кодировщик Base58 — удобный для человека алфавит в стиле Bitcoin

Дополнительное чтение:
Что такое Base64 и как он работает?
URL-safe против стандартного Base64 — подробная история
Base64 для UTF-8 и Unicode