ToolDeck

Base64

7 инструментов

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

Кодирование — это процесс преобразования данных из одного представления в другое. В веб-разработке кодирование используется для безопасной передачи данных через каналы, предназначенные для ограниченного набора символов. Например, при отправке двоичных данных через текстовый протокол или при включении специальных символов в URL. Понимание принципов кодирования позволяет избежать незаметных ошибок и уязвимостей безопасности, которые возникают при некорректной обработке данных.

Кодировка символов определяет, как текстовые символы отображаются на байты. Base64 преобразует двоичные данные в ASCII-текст. URL-кодирование делает произвольный текст безопасным для использования в URL. Важно понимать, что кодирование не является шифрованием: закодированные данные можно легко декодировать без какого-либо ключа. Правильный выбор схемы кодирования зависит от контекста: типа данных, используемого протокола и требований к переносимости.

История кодировок символов

Кодировка символов — это отображение между символами и их двоичными представлениями:

ASCII1963
128 символов

7-битный американский стандартный код. 128 символов: английские буквы, цифры, знаки препинания и управляющие коды.

Latin-11987
256 символов

Расширенный ASCII для западноевропейских языков. Добавлено 128 символов. Не подходит для не-латинских письменностей.

Unicode1991
149 186+ символов

Универсальный набор символов, охватывающий все системы письма мира. Определяет кодовые точки для более чем 149 000 символов.

UTF-81993
Весь Unicode символов

Кодировка Unicode переменной ширины, использующая 1–4 байта на символ. Совместима с ASCII. Доминирующая кодировка в вебе.

UTF-161996
Весь Unicode символов

Кодировка переменной ширины с использованием 2 или 4 байт на символ. Используется внутри Windows, Java и строк JavaScript.

UTF-322000
Весь Unicode символов

Кодировка фиксированной ширины: всегда 4 байта на символ. Редко встречается в вебе.

Почему победил UTF-8

UTF-8 стал доминирующим, потому что обратно совместим с ASCII, самосинхронизирующийся и экономичный по размеру для латинского текста. Любой ASCII-документ является допустимым UTF-8-документом.

Кодирование Base64

Base64 преобразует двоичные данные в текстовое представление, используя только 64 печатных ASCII-символа: буквы A–Z и a–z, цифры 0–9, а также символы + и /. Это необходимо, когда двоичные данные должны передаваться через текстовые каналы. Вложения электронной почты, data URI в HTML и CSS, JWT-токены и HTTP Basic Auth — всё это использует Base64. Алфавит из 64 символов выбран намеренно: каждый символ несёт ровно 6 бит информации, что позволяет аккуратно разбивать входной поток байтов на группы и кодировать их без потерь.

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

Base64 группирует входные байты в 3-байтные (24-битные) блоки и кодирует каждый блок как 4 Base64-символа (по 6 бит каждый). Именно поэтому соотношение размеров закодированных и исходных данных составляет 4:3 — то есть Base64 увеличивает объём данных приблизительно на 33%. Если входные данные не кратны 3 байтам, добавляются символы заполнения =:

ВходБайты hexBase64
"Man"77 61 6ETWFu
"Ma"4D 61TWE=
"M"4DTQ==

Символы = в конце указывают, сколько байт не хватало для завершения последней 3-байтной группы. Один символ = означает, что нужен был один байт заполнения; два символа == означают, что нужны были два байта. Стандартный Base64 всегда производит вывод, длина которого кратна 4. В URL-безопасном варианте Base64url символ заполнения = часто опускается, поскольку он является зарезервированным символом в URL и требовал бы дополнительного процентного кодирования.

URL-кодирование

URL может содержать только ограниченный набор безопасных ASCII-символов. Любой символ вне этого набора должен быть процентно-закодирован.

Процентное кодирование заменяет каждый небезопасный байт символом %, за которым следуют два шестнадцатеричных цифры значения этого байта.

Часто кодируемые символы

СимволЗакодированоПримечания
Space%20Наиболее распространённый; используется в отправке форм как + в application/x-www-form-urlencoded
&%26Разделитель строки запроса; должен кодироваться как литеральное значение
=%3DРазделитель ключ-значение в строках запроса; кодировать как данные
+%2BИнтерпретируется как пробел в application/x-www-form-urlencoded; кодировать для сохранения +
#%23Идентификатор фрагмента; кодировать как литеральные данные в пути или запросе
/%2FРазделитель сегмента пути; кодировать как литеральные данные
:%3AРазделитель схемы; кодировать в контекстах пути и запроса
@%40Используется в mailto: и auth; кодировать как литеральные данные

encodeURI против encodeURIComponent

JavaScript предоставляет две функции кодирования с разной областью действия. encodeURI кодирует полный URL. encodeURIComponent кодирует компонент URL — все символы кроме A-Z, a-z, 0-9, -, _, ., ~.

Где кодирование встречается в веб-разработке

HTTP Basic-аутентификация

Заголовок Authorization: Basic кодирует учётные данные как Base64(пользователь:пароль). Это кодирование для удобства транспортировки, а НЕ безопасность — Base64 тривиально обратим, и любой, кто перехватит заголовок, мгновенно получит учётные данные в открытом виде. Всегда используйте HTTPS с Basic Auth.

Data URI

Data URI встраивают содержимое файла прямо в HTML или CSS: data:image/png;base64,.... Это исключает HTTP-запросы ценой увеличения размера документа на ~33% из-за накладных расходов Base64.

MIME-вложения электронной почты

Электронная почта была разработана для 7-битного ASCII. Двоичные вложения — изображения, PDF-файлы, архивы — кодируются MIME в Base64 перед передачей, что указывается заголовком Content-Transfer-Encoding: base64. Почтовый клиент прозрачно декодирует их при отображении письма.

JWT-токены

JWT-токены используют кодирование Base64url для всех трёх частей — заголовка, полезной нагрузки и подписи — делая их безопасными для URL без дополнительного процентного кодирования.

Параметры строки запроса

Любые пользовательские данные в строках запроса URL должны быть процентно-закодированы. Если не закодировать символы & или = внутри значения параметра, это приведёт к незаметному нарушению разбора строки запроса.

Интернационализированные доменные имена

Доменные имена с не-ASCII-символами кодируются с помощью Punycode (префикс xn--) для совместимости с DNS.

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

Является ли Base64 формой шифрования?

Нет. Base64 — это кодирование, а не шифрование. Это обратимое преобразование без секретного ключа: любой, кто видит строку Base64, может декодировать её мгновенно с помощью любого стандартного инструмента. Никогда не используйте Base64 в качестве меры безопасности для защиты конфиденциальных данных.

Почему вывод Base64 иногда оканчивается ==?

Base64 обрабатывает вход группами по 3 байта. Если вход не кратен 3, добавляется заполнение = для выравнивания последней группы до 4 символов. Один символ = означает один байт заполнения, два символа == — два байта. Некоторые реализации, например Base64url для JWT, опускают заполнение.

В чём разница между Base64 и Base64url?

Base64url — URL-безопасный вариант Base64, который заменяет + на - и / на _, и обычно не использует символ заполнения =. Это делает его пригодным для использования в URL и HTTP-заголовках без дополнительного процентного кодирования. JWT используют Base64url для всех трёх частей, а также этот вариант применяется в OAuth 2.0 PKCE и других протоколах, где токены передаются в строках запроса.

Когда использовать encodeURI вместо encodeURIComponent?

Используйте encodeURIComponent для отдельных значений. encodeURI — для полной URL-строки, где нужно сохранить символы структуры URL.

Почему UTF-8 лучше UTF-16 для веба?

UTF-8 совместим с ASCII и экономичен для латинского текста. HTTP и HTML по умолчанию используют UTF-8.

Что такое процентное кодирование?

Процентное кодирование представляет символы как % с двузначным шестнадцатеричным значением байта. Пробел — %20. Многобайтовые UTF-8-символы кодируют каждый байт отдельно: например, символ é кодируется как %C3%A9.

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

Base64 увеличивает размер данных примерно на 33% и добавляет нагрузку на CPU при кодировании и декодировании. В системах с высокой пропускной способностью предпочтительнее использовать бинарные протоколы, такие как gRPC или бинарный WebSocket. URL-кодирование добавляет минимальные накладные расходы по процессорному времени, но может значительно увеличить длину URL при наличии многих специальных символов.

Что такое Punycode?

Punycode — кодировка для представления Unicode-символов в ASCII-совместимой DNS-системе. Домены вроде münchen.de кодируются как xn--mnchen-3ya.de.