webtrajans
ru

Base64 и URL-кодирование: как работают и когда их использовать

Base64 превращает любые байты в безопасный текст, а URL-кодирование делает строку пригодной для адреса страницы. Оба способа обратимы и ничего не скрывают — это не шифрование.

Обновлено: 5 мин чтения

Если вы видели в ссылке что-то вроде %D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0 или строку 0J/RgNC40LLQtdGC в коде, вы встречали URL-кодирование и Base64. Это две разные техники с одной целью: передать данные через каналы, которые принимают ограниченный набор символов. Разберём, как они работают и где чаще всего ошибаются.

Зачем вообще кодировать

Многие протоколы и форматы исторически рассчитаны на ограниченный набор символов:

  • электронная почта изначально передавала только 7-битный ASCII-текст;
  • URL допускает латинские буквы, цифры и несколько служебных символов;
  • JSON, XML, HTML — текстовые форматы, в которые нельзя просто вставить бинарный файл.

Кодирование переводит данные в безопасное подмножество символов, а на другой стороне их декодируют обратно без потерь.

Как работает Base64

Base64 использует 64 символа: A–Z, a–z, 0–9, + и /, плюс = для выравнивания.

Алгоритм:

  1. Берутся 3 байта (24 бита).
  2. Делятся на 4 группы по 6 бит.
  3. Каждая группа (число от 0 до 63) заменяется символом из алфавита.
  4. Если в конце не хватает байтов, добавляется = или ==.

Примеры:

Исходный текст Base64
Man TWFu
Ma TWE=
Hi! SGkh
Привет 0J/RgNC40LLQtdGC

Слово «Привет» в UTF-8 занимает 12 байт (по 2 байта на букву), поэтому превращается в 16 символов Base64. Закодировать и раскодировать строку можно в Base64-декодере.

Base64URL

Символы + и / имеют особое значение в URL, поэтому существует вариант Base64URL: + заменяется на -, / — на _, а = часто отбрасывается. Его используют, например, в JWT-токенах.

Где применяется Base64

  • Вложения в письмах (MIME): файлы кодируются в Base64 и становятся примерно на треть больше. Поэтому реальный лимит вложения меньше номинального — подробнее в гайде Как сжать PDF.
  • Data URL — встраивание небольших изображений прямо в HTML или CSS:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="">
  • HTTP Basic Auth — логин и пароль передаются как Base64(login:password). Это не защищает их, поэтому Basic Auth допустим только поверх HTTPS.
  • JWT, ключи и сертификаты (формат PEM), бинарные данные в JSON и API.

Когда data URL — плохая идея

Встраивание картинок через Base64 экономит HTTP-запрос, но увеличивает размер на ~33 %, не кешируется отдельно и замедляет разбор HTML/CSS. Подходит для иконок до нескольких килобайт, а не для фотографий. Об оптимизации изображений — в гайде Оптимизация изображений для сайта.

Как работает URL-кодирование

Процентное кодирование (percent-encoding, RFC 3986) заменяет недопустимый символ на % и две шестнадцатеричные цифры каждого его байта в UTF-8.

Не кодируются («незарезервированные»): A–Z a–z 0–9 - _ . ~.

Зарезервированные символы имеют служебное значение и кодируются, если входят в данные: : / ? # [ ] @ ! $ & ' ( ) * + , ; =.

Примеры:

Исходная строка Закодированная
пробел %20
& %26
Москва %D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0
цена 100 ₽ & скидка %D1%86%D0%B5%D0%BD%D0%B0%20100%20%E2%82%BD%20%26%20...

Знак рубля ₽ занимает в UTF-8 три байта и кодируется как %E2%82%BD. Проверить любую строку можно в URL-кодировщике.

Кириллические домены

Домен пример.рф в URL не кодируется процентами — для доменов используется Punycode: xn--e1afmkfd.xn--p1ai. А вот путь и параметры после домена кодируются процентным кодированием.

encodeURI и encodeURIComponent

В JavaScript есть две функции, и их часто путают:

encodeURIComponent('цена 100 ₽ & скидка');
// "%D1%86%D0%B5%D0%BD%D0%B0%20100%20%E2%82%BD%20%26%20%D1%81..."

encodeURI('https://site.ru/поиск?q=a b');
// "https://site.ru/%D0%BF%D0%BE%D0%B8%D1%81%D0%BA?q=a%20b"
  • encodeURIComponent — для значения одного параметра: кодирует и &, =, /, ?.
  • encodeURI — для целого адреса: служебные символы URL оставляет.

Если передать значение с & через encodeURI, параметр «развалится» на два.

Кодирование — не шифрование

Это главное заблуждение. И Base64, и URL-кодирование полностью обратимы без ключа. Строку cGFzc3dvcmQ= раскодирует кто угодно — это слово password.

  • Для защиты данных при передаче используется TLS/HTTPS.
  • Для хранения паролей — хеширование со специальными алгоритмами (bcrypt, Argon2). Подробнее — в гайде Как придумать надёжный пароль.
  • Для конфиденциальных данных — шифрование с ключом.

Base64 в командной строке

Закодировать и раскодировать данные можно без онлайн-сервисов:

# Linux / macOS
echo -n 'Привет' | base64        # 0J/RgNC40LLQtdGC
echo '0J/RgNC40LLQtdGC' | base64 --decode

# Windows PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('Привет'))

Флаг -n у echo важен: без него в кодируемые данные попадёт перевод строки, и результат будет другим. Это частая причина того, что «одна и та же строка» даёт разный Base64 в разных инструментах.

HTML-сущности — ещё один вид кодирования

В HTML спецсимволы записывают сущностями: &lt; вместо <, &amp; вместо &, &quot; вместо кавычки. Это нужно, чтобы браузер не принял текст за разметку. Путать HTML-сущности с URL-кодированием не стоит: в атрибуте href амперсанд между параметрами записывается как &amp;, а значения параметров при этом кодируются процентами.

Как понять, что перед вами Base64

Признаки: строка состоит только из латинских букв, цифр, + и / (или - и _), её длина кратна четырём, а в конце может стоять один или два знака =. Если после декодирования получается осмысленный текст или узнаваемая сигнатура файла (например, iVBORw0KGgo — начало PNG, JVBERi0 — начало PDF), это действительно Base64.

Частые ошибки

  • Двойное кодирование: %20 превращается в %2520. Кодируйте значения один раз, непосредственно перед подстановкой в URL.
  • Неправильная кодировка исходного текста: кириллица в Windows-1251 даёт другие байты, чем в UTF-8. Современный стандарт — UTF-8.
  • Плюс вместо пробела: в параметрах форм + означает пробел, поэтому настоящий плюс в номере телефона нужно кодировать как %2B.
  • Base64 без учёта URL: обычный Base64 с + и / в ссылке ломается — используйте Base64URL.
  • «Спрятать» токен в Base64 — он остаётся открытым.

Чек-лист

  • Значения параметров кодируются encodeURIComponent или аналогом.
  • Исходный текст в UTF-8.
  • Нет двойного кодирования.
  • Для URL используется Base64URL, а не обычный Base64.
  • Секреты защищены шифрованием или HTTPS, а не Base64.

Частые вопросы

Base64 — это шифрование?

Нет. Base64 — способ представления данных, а не защита. Любой может декодировать строку без ключа. Пароли и персональные данные нельзя «прятать» в Base64.

Почему русские буквы в ссылке превращаются в %D0%..?

URL допускает только ограниченный набор ASCII-символов. Кириллица кодируется в UTF-8, и каждый байт записывается как %XX. Буква «М» занимает два байта и превращается в %D0%9C.

Насколько Base64 увеличивает размер?

Примерно на 33 %: каждые 3 байта превращаются в 4 символа. Из-за этого вложения в письмах и картинки в data URL «весят» больше исходных файлов.

Чем пробел %20 отличается от плюса в URL?

В пути URL пробел кодируется как %20. В параметрах HTML-форм (application/x-www-form-urlencoded) пробел исторически кодируется знаком +. Надёжнее всегда использовать %20, а знак плюса в значении кодировать как %2B.

Похожие гайды

Регулярные выражения: шпаргалка и практические примерыРегулярные выражения (regex) — компактный язык для поиска и проверки текста. Ниже — основной синтаксис, готовые шаблоны для российских телефонов, дат и email и ловушки, на которых ошибаются чаще всего.Индекс массы тела: как рассчитать ИМТ и правильно понять результатИМТ — простой способ оценить, соответствует ли вес росту. Он удобен для скрининга, но не показывает, из чего состоит вес, поэтому его стоит дополнять другими измерениями.Сколько калорий нужно в день: расчёт нормы по формулеСуточная норма калорий складывается из базового обмена и затрат на движение. Её можно оценить по формуле Миффлина — Сан Жеора, но результат остаётся ориентиром, а не точной цифрой.Контрастность цветов по WCAG: как проверить и исправитьСерый текст на белом фоне выглядит стильно, но многие люди его не прочитают. Стандарт WCAG задаёт минимальную контрастность, а проверить её можно за секунды.