Base64 — что это и как работает
Принцип кодирования Base64, алфавит, padding, использование в Data URI, email, API. Примеры кодирования.
Введение
Base64 — это способ представления произвольных бинарных данных в виде строки, состоящей исключительно из печатных ASCII-символов. Изначально схема разработана для нужд электронной почты MIME, где любой附件 должен пройти через текстовые каналы связи, не допускающие байты с установленным старшим битом. Сегодня Base64 встречается везде: в JSON Web Token, в Data URI внутри HTML и CSS, в API REST, в файловых хранилищах и даже в куки-файлах. В этой статье мы разберём, как устроено Base64 кодирование, какой у него алфавит, что такое padding и почему «Base64» не означает «шифрование».
Если вам нужно быстро закодировать или раскодировать строку, используйте наши инструменты:Base64 кодировщик и Base64 декодер. Они работают прямо в браузере и не отправляют данные на сервер.
Зачем нужно кодирование Base64
Любые данные в компьютере хранятся в виде последовательности байтов. Каждый байт может принимать 256 значений — от 0 до 255. При этом многие протоколы и форматы (email, HTTP-заголовки, JSON, XML) рассчитаны только на текст и не позволяют передавать произвольные байты напрямую. Если в потоке появится нулевой байт или символ с кодом выше 127, промежуточные узлы могут его «съесть», заменить или интерпретировать как управляющий.
Base64 решает эту проблему радикально: любые входные байты преобразуются в строку, содержащую только 64 «безопасных» символа из таблицы ASCII. Такая строка гарантированно пройдёт через любой текстовый канал без искажений. Цена — увеличение размера примерно на 33%, потому что каждые три байта исходных данных превращаются в четыре символа.
Алфавит Base64
Стандартный алфавит Base64 описан в RFC 4648 и состоит из 64 символов: 26 заглавных букв латиницы (A–Z), 26 строчных (a–z), 10 цифр (0–9) и двух дополнительных символов — плюса (+) и слэша (/). Знак равенства (=) используется как символ выравнивания (padding) и не входит в основной алфавит.
| Индекс | Символ | Индекс | Символ | Индекс | Символ | Индекс | Символ |
|---|---|---|---|---|---|---|---|
| 0 | A | 16 | Q | 32 | g | 48 | w |
| 1 | B | 17 | R | 33 | h | 49 | x |
| 2 | C | 18 | S | 34 | i | 50 | y |
| 3 | D | 19 | T | 35 | j | 51 | z |
| 4 | E | 20 | U | 36 | k | 52 | 0 |
| 5 | F | 21 | V | 37 | l | 53 | 1 |
| 6 | G | 22 | W | 38 | m | 54 | 2 |
| 7 | H | 23 | X | 39 | n | 55 | 3 |
| 8 | I | 24 | Y | 40 | o | 56 | 4 |
| 9 | J | 25 | Z | 41 | p | 57 | 5 |
| 10 | K | 26 | a | 42 | q | 58 | 6 |
| 11 | L | 27 | b | 43 | r | 59 | 7 |
| 12 | M | 28 | c | 44 | s | 60 | 8 |
| 13 | N | 29 | d | 45 | t | 61 | 9 |
| 14 | O | 30 | e | 46 | u | 62 | + |
| 15 | P | 31 | f | 47 | v | 63 | / |
Существуют и вариации алфавита. Вариант Base64url заменяет «+» на «-», а «/» на «_», чтобы строку можно было безопасно использовать в URL и именах файлов без percent-encoding. Именно Base64url применяется в JWT — подробнее в статье о структуре JWT токена.
Как работает Base64: пошаговый алгоритм
Принцип кодирования очень прост. Берём входной поток байтов, разбиваем его на группы по три байта (24 бита) и каждую такую группу делим на четыре 6-битных куска. Каждые 6 бит дают число от 0 до 63 — это индекс в алфавите Base64, по которому выбирается символ.
Пример: кодируем строку «Cat»
Строка «Cat» в ASCII состоит из трёх байтов: 0x43 0x61 0x74. В двоичном виде это:
01000011 01100001 01110100Разбиваем 24 бита на четыре 6-битных группы:
010000 110110 000101 110100
= 16 = 54 = 5 = 52
= Q = 2 = F = 0Итог: Q2F0. Проверим в JavaScript:
const encoded = btoa('Cat');
console.log(encoded); // "Q2F0"
const decoded = atob('Q2F0');
console.log(decoded); // "Cat"Что происходит с «хвостом»
Если длина входных данных не кратна трём, остаются «лишние» байты — один или два. Тогда последний блок дополняется нулями до 6 бит, а недостающие символы заменяются знаком равенства. Это и есть padding.
- 1 байт (8 бит) → 2 символа Base64 + «==»
- 2 байта (16 бит) → 3 символа Base64 + «=»
- 3 байта (24 бита) → 4 символа, padding не нужен
Пример: кодируем «C» (один байт):
btoa('C'); // "Qw=="
btoa('Ca'); // "Q2E="
btoa('Cat'); // "Q2F0"Где применяется Base64
Электронная почта и MIME
Исторически первая область применения. Сообщение MIME помечает бинарное вложение заголовкомContent-Transfer-Encoding: base64, после чего содержимое кодируется в Base64. Так почтовые серверы гарантированно передают файлы без повреждений.
Data URI в HTML и CSS
Небольшие изображения, шрифты и SVG можно встроить прямо в HTML или CSS с помощью схемыdata:. Например:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="иконка">Подробно об этой технике читайте в статье о Data URI scheme.
JSON Web Token
JWT состоит из трёх частей: header, payload и signature. Каждая часть — это JSON, сериализованный и кодированный в Base64url. Это позволяет передавать токен в HTTP-заголовкеAuthorization: Bearer ... без экранирования. Подробнее — в материале о JWT токене.
API и REST
Бинарные данные (файлы, изображения) в JSON API часто передают в виде Base64-строки в теле запроса. Это удобно, но увеличивает объём передаваемых данных примерно на треть — для больших файлов лучше использовать multipart/form-data.
Base64 — это не шифрование
Распространённая ошибка начинающих разработчиков — использовать Base64 как способ скрыть данные от посторонних. Это опасное заблуждение: Base64 кодирование обратимо, и любой, у кого есть закодированная строка, может раскодировать её за секунду. Алгоритм публичный, стандартный, и не предусматривает никакого ключа.
Если нужно защитить данные — используйте настоящие криптографические primitives: симметричное шифрование (AES), хеширование с солью (bcrypt, scrypt) или подпись сообщения (HMAC). Подробнее о HMAC — в нашей статье про аутентификацию сообщений.
Размер и эффективность
Главная плата за «безопасность канала» — рост объёма. Формула проста:ceil(4 × n / 3), то есть на каждые три входных байта получается четыре символа. С учётом padding итоговый размер всегда кратен четырём байтам.
| Размер исходных данных | Размер в Base64 | Рост |
|---|---|---|
| 1 КБ | 1.37 КБ | +37% |
| 10 КБ | 13.7 КБ | +37% |
| 100 КБ | 137 КБ | +37% |
| 1 МБ | 1.37 МБ | +37% |
Для коротких строк относительная «дороговизна» менее заметна, а вот встраивание в Data URI фотографий по несколько мегабайт сильно раздувает HTML. Кроме того, браузер не кеширует встроенные ресурсы независимо от страницы — каждый раз при повторном заходе они загружаются заново.
Частые ошибки при работе с Base64
1. Использование строкового конструктора для бинарных данных
// НЕПРАВИЛЬНО: теряем байты со старшим битом
const broken = btoa(String.fromCharCode(...imageBytes));
// ПРАВИЛЬНО: используем Uint8Array и TextDecoder
const bytes = new Uint8Array(imageData);
let binary = '';
for (let i = 0; i < bytes.length; i++) {
binary += String.fromCharCode(bytes[i]);
}
const base64 = btoa(binary);2. Игнорирование кодировки символов
btoa() работает только с Latin1 символами. Если попытаться закодировать кириллицу напрямую, будет выброшено исключение. Сначала нужно преобразовать строку в UTF-8 байты:
function encodeUtf8(str) {
return btoa(unescape(encodeURIComponent(str)));
}
function decodeUtf8(b64) {
return decodeURIComponent(escape(atob(b64)));
}
encodeUtf8('Привет, мир!');
// "D0/fgD8PfgD8PfgD8PfgD8PfgD8PfgD8PfgD8PfgD8PfgD8"3. Путаница с Base64 и Base64url
Стандартный Base64 содержит символы «+» и «/», которые в URL имеют особый смысл. Если вставить такую строку в query-параметр без экранирования, сервер получит искажённые данные. Решение — либо использовать Base64url, либо применять URL encoding. О нём — в статье про percent-encoding.
Base64 в разных языках программирования
JavaScript (Node.js)
// Кодирование
const encoded = Buffer.from('Привет, мир!', 'utf8').toString('base64');
// Декодирование
const decoded = Buffer.from(encoded, 'base64').toString('utf8');Python
import base64
# Кодирование
encoded = base64.b64encode('Привет, мир!'.encode('utf-8')).decode('ascii')
# Декодирование
decoded = base64.b64decode(encoded).decode('utf-8')PHP
<?php
$encoded = base64_encode('Привет, мир!');
$decoded = base64_decode($encoded);Безопасность и best practices
- Не используйте Base64 как защиту. Это кодирование, а не шифрование. Для конфиденциальных данных применяйте AES или хотя бы XOR с ключом достаточной длины.
- Проверяйте длину. Корректная Base64-строка всегда кратна четырём символам; если это не так — данные повреждены.
- Учитывайте padding. Большинство декодеров терпимо относятся к отсутствию «=», но стандарт требует их наличия.
- В URL используйте Base64url. Это убережёт от неожиданностей с экранированием.
- Не вставляйте большие файлы в Data URI. Для изображений больше 10–20 КБ лучше использовать обычную ссылку на файл — это ускорит загрузку страниц.
Заключение
Base64 — простой, надёжный и повсеместно поддерживаемый способ преобразовать бинарные данные в текстовый формат. Он незаменим в email, JWT, Data URI, API и во многих других задачах, где данные должны пройти через текстовый канал без искажений. Главное — помнить, что Base64 не является шифрованием и не защищает данные от прочтения; его задача принципиально иная — обеспечить совместимость с текстовыми протоколами.
Чтобы быстро кодировать и декодировать строки в браузере без отправки на сервер, воспользуйтесь нашими инструментами: Base64 кодировщик и Base64 декодер. А если хотите разобраться, чем Base64 отличается от других методов кодирования, — читайте наш сравнительный обзор.
Попробуйте эти инструменты
Похожие статьи
URL кодирование: percent-encoding explained
Что такое URL encoding, зарезервированные символы, как кодировать/декодировать URL, частые ошибки.
HTML сущности и кодирование спецсимволов
HTML entities, named vs numeric, XSS защита, кодирование кавычек, амперсандов, угловых скобок.
JWT токен: структура и как декодировать
JSON Web Token: header, payload, signature. Как работает аутентификация JWT, безопасность, декодирование.
Unicode и UTF-8: как работает кодировка
История Unicode, UTF-8 vs UTF-16, BOM, кодирование кириллицы, эмодзи, проблемы кодировок.