Если вы видели в ссылке что-то вроде %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, + и /, плюс = для выравнивания.
Алгоритм:
- Берутся 3 байта (24 бита).
- Делятся на 4 группы по 6 бит.
- Каждая группа (число от 0 до 63) заменяется символом из алфавита.
- Если в конце не хватает байтов, добавляется
=или==.
Примеры:
| Исходный текст | 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 спецсимволы записывают сущностями: < вместо <, & вместо &, " вместо кавычки. Это нужно, чтобы браузер не принял текст за разметку. Путать HTML-сущности с URL-кодированием не стоит: в атрибуте href амперсанд между параметрами записывается как &, а значения параметров при этом кодируются процентами.
Как понять, что перед вами 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.