Обзор
Base64 - обратимое превращение, и этот инструмент - обратная половина пути: он берёт печатный текст, который создал кодировщик, и превращает его обратно в исходные данные. Вставьте строку, выберите настройки, подходящие под то, откуда она пришла, и результат декодирования будет готов к прочтению или копированию. Если данные - двоичные, например изображение или архив, их Base64-текст хранится в обычном файле: форма загрузки на этой странице принимает такой файл и отдаёт исходные двоичные данные в виде файла для скачивания. Соответствующий кодировщик находится на сестринском сайте - в одном клике отсюда.
Дополнительные параметры
- Набор символов: Base64 перемещает байты, а не буквы, поэтому результат декодирования читается правильно только если известно, в каком наборе символов он был сохранён до кодирования. Выберите тот, что соответствует вашему источнику: UTF-8 для современного текста, Windows-1252 или вариант ISO-8859 для старых документов, либо АВТОМАТИЧЕСКОЕ ОБНАРУЖЕНИЕ, чтобы инструмент решил сам (результат определения показывается прямо рядом со списком, а если инструмент не может разобраться - считается, что это UTF-8). Если на выходе что-то напоминает перемешанный алфавит, этот параметр - первый, с которым стоит поэкспериментировать. Файлы - исключение: двоичные данные декодируются как есть, без какой-либо конвертации.
- Декодировать каждую строку отдельно: По умолчанию весь ввод - это один непрерывный поток данных: перед декодированием переносы строк и пробелы удаляются, поэтому строка, разбитая на несколько линий и скопированная прямо из письма, просто работает, а URL-безопасные символы
-и_принимаются на месте+и/. Отметьте этот флажок, если во вводе - список независимых записей: тогда каждая строка декодируется сама по себе, и результаты возвращаются, по одному на строку. Форма загрузки предлагает тот же параметр. - Режим реального времени: Включите его - и декодирование будет происходить прямо в вашем браузере по мере ввода, повторяясь при каждом нажатии клавиши: на наши серверы при этом ничего не отправляется. Режим учитывает параметр построчного декодирования и работает только с UTF-8, поэтому список наборов символов остаётся заблокированным, пока он включён, а кнопка декодирования - неактивной, пока вы не отключите его.
Безопасно и надёжно
Всё работает по шифрованному HTTPS-соединению, и ничего из отправленного не сохраняется: загруженные файлы удаляются в момент обработки, а скачиваемый результат исчезает сразу после первой попытки его загрузки или через 15 минут бездействия - что наступит раньше. Содержимое того, что вы отправляете, никогда не хранится; единственная обработка помимо самого преобразования - сканирование загруженных файлов на безопасность, которое нужно, чтобы блокировать вредоносный или неподобающий контент. В режиме реального времени ваш текст никогда не покидает браузер. Все подробности - в нашей политике конфиденциальности, ссылка на неё в подвале страницы ниже.
Полностью бесплатно
Всё на этой странице можно использовать бесплатно - полный список наборов символов, загрузка файлов и режим реального времени. Без аккаунта, без установки программного обеспечения, без платной стены: для такой небольшой задачи - именно так и должно быть.
Как устроен Base64
Некоторые данные просто не могут пройти по текстовому каналу: фотография, архив, хеш, фрагмент двоичных данных, от которого 7-битное почтовое соединение заглохло бы. Base64 - переводчик для таких случаев. Он переписывает любую последовательность байтов в простой печатный текст, чтобы данные могли жить в теле письма, JSON-документе, XML-файле или в URL и прийти именно в том виде, в каком ушли. Перевод полностью обратим: каждый байт возвращается, в том же порядке, и ничего по дороге не теряется.
Весь формат умещается в одном предложении: три байта на входе - четыре символа на выходе. Цена - результат примерно на треть больше оригинала. Награда - строка, которая выглядит как текст, ведёт себя как текст и проходит по каналам, которые уничтожили бы сырые байты. И стоит сразу уточнить, чем Base64 не является: это не шифрование и не сжатие. Это обратимое превращение, и в этом его вся работа.
Почему 64, и почему именно эти символы
Байт содержит 8 бит, но старые текстовые каналы, в первую очередь почта, безопасно передавали только 7-битный ASCII. Хитрость в том, чтобы выбрать алфавит из печатных символов, который переживёт любой такой путь, и подобрать его размер так, чтобы математика сходилась без остатка. При 64 символах каждый закодированный символ несёт ровно 6 бит, а 24 делится и на 8 (байт), и на 6 (символ): три входных байта превращаются в четыре выходных символа без остатка. Название - это просто основание той системы счисления, как 10 для наших цифр.
Стандартный алфавит - это 62 буквы и цифры: A-Z, a-z и 0-9, а в качестве последних двух - + и /. Спецификация добавляет 65-й символ, =, который вообще не входит в алфавит: он появляется только в конце, в качестве заполнения. Выбор был осознанным. Весь набор - печатные символы; он общий для всех текстовых систем; а спецификация MIME отмечает, что он записан одинаково во всех версиях ISO 646, включая US-ASCII, и во всех версиях EBCDIC. Именно это последнее свойство держит данные в целости, пока они проходят через старую технику раннего интернета, не готовую к восьми битам.
| Значение | Символ | Значение | Символ | Значение | Символ | Значение | Символ |
|---|---|---|---|---|---|---|---|
| 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 | / |
| (65-й символ, =, - это заполнитель: он никогда не несёт данные; он лишь помечает конец.) | |||||||
Кодирование шаг за шагом
Кодировщик - это четырёхзвенный конвейер. Он читает вход по три байта за раз и сливает каждый триплет в одну 24-битную строку. Эта строка нарезается на четыре куска по 6 бит. Каждый кусок - это число от 0 до 63, и каждое число ищется в таблице выше. Четыре числа на входе - четыре символа на выходе.
Посмотрим, как это работает на слове foo, которое приходит в виде значений байтов 102, 111 и 111 (шестнадцатеричные 66, 6F, 6F). Сложенные вместе, 24 бита выглядят так: 01100110 01101111 01101111. Разрезанные по шесть, получаем 011001, 100110, 111101 и 101111, то есть 25, 38, 61 и 47. Таблица говорит, что это Z, m, 9 и v, так что foo кодируется в Zm9v, и любой Base64-декодировщик в мире вернёт обратно исходные три байта.
| Шаг | 1-й байт | 2-й байт | 3-й байт | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Текст | f | o | o | |||||||||||||||||||||
| Значение байта | 102 | 111 | 111 | |||||||||||||||||||||
| Шестнадцатеричное | 66 | 6F | 6F | |||||||||||||||||||||
| Биты | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 |
| 6-битное значение | 25 | 38 | 61 | 47 | ||||||||||||||||||||
| Символ | Z | m | 9 | v | ||||||||||||||||||||
Остальной вход обрабатывается так же, триплет за триплетом, пока не кончится. Только последняя группа, когда в ней меньше трёх байтов, требует особого хода.
Заполнение: = в конце
Вход всегда состоит из целого числа байтов, но на три оно делится не всегда без остатка. Когда в хвосте остаётся один или два байта, кодировщику всё равно нужно завершить полную группу из четырёх символов. Он заполняет недостающие биты нулями, делает подстановки как обычно и заменяет символы, которые дали бы биты заполнения, на знаки =. Возможны ровно три варианта завершения:
| Хвост входа | Кодированный хвост | Декодируется обратно в |
|---|---|---|
| 3 байта | 4 символа, без заполнения | 3 байта |
| 2 байта | 3 символа + 1 = | 2 байта |
| 1 байт | 2 символа + 2 = | 1 байт |
Так fo, два байта, становится Zm8=, а одинокий f превращается в Zg==, тогда как foo не нуждается в заполнении вообще. Декодировщик точно знает, что делать с заполнителями: каждый = означает ещё восемь нулевых битов, которые выбрасываются. Заполнители сидят только в самом конце, и их не больше двух. Спецификация MIME даже использует это в своих интересах: поскольку = не может встречаться нигде больше, данные с заполнением сами объявляют о своём конце, и получатель видит, что данные не были усечены по пути. И самый мелкий случай: пустой вход кодируется в пустой выход. Даже «ничего» проходит идеальный круг.
Декодирование: конвейер в обратную сторону
Декодирование - это та же машина, работающая задом наперёд, и она не менее механична. Берём четыре символа, ищем настоящие (заполнитель заменяет шесть нулей), записываем 24 бита и отдаём первые 16 бит, если есть один заполнитель, или все 24, если их нет. Четыре символа на входе - три байта на выходе; два байта на выходе при одном заполнителе; один байт при двух. Нулевые биты, добавленные кодировщиком, - единственное, что выбрасывается, а каждый другой бит - ровно тот, что был на входе. Вот что на самом деле означает «обратимое» здесь: сам формат без потерь, и единственное, что может повредить ваши данные, - это канал, который исказит строку, или декодировщик, который тихо сдастся.
Поэтому стандарт строг в одном: в символах, которых нет в алфавите. RFC 4648 говорит, что декодировщик должен отклонять данные, несущие любой символ вне 64, если окружающая спецификация явно это не разрешает. Причина практическая, а не педантическая. Декодировщик, который тихо проглатывает чужие символы, можно обмануть: прокравшиеся символы становятся скрытым боковым каналом, и эту уловку уже использовали, чтобы прятать данные от фильтров и раскапывать ошибки декодировщиков. Знаменитое исключение - сам MIME, который старше стандарта и говорит обратное: игнорируй каждый символ вне алфавита, - именно так переносы строк проходят в вложении письма. Если вы сами проверяете вход, то современное правило и есть верное: если ваша строка несёт @, пробел или что-нибудь ещё, чего нет в таблице, - это не чистый Base64.
Переносы строк и правило 76 символов
Вам часто попадётся Base64, разбитый на строки, и эта привычка пришла из почты. Старая SMTP-машина имела ограничения на длину строки, поэтому MIME переносит данные по 76 символов на строку с разрывом CRLF, а более старый формат PEM, тот, что несёт сертификаты и ключи, переносит по 64. Правило RFC 4648 для нового кода - обратное: не добавляйте переносы строк вообще, если формат, который вы реализуете, не говорит, что они нужны. На практике декодировщику всё равно. Перенос строки - всего лишь символ вне алфавита, поэтому данные, обёртые MIME, блок PEM и одна длинная неразрывная строка декодируются в одни и те же байты. Если вы вставляете Base64 откуда угодно - сначала уберите переносы строк, и всё.
Переносы имеют небольшую цену, и она видна в расчётах размера. Без переносов строк Base64 - это ровно четыре трети оригинала, примерно на 33 процента больше. Разбитый по 76 символов с разрывами CRLF, он примерно на 37 процентов больше, поэтому файл, который должен весить 100 КБ, часто приходит примерно 137 КБ текста. Математика всегда сходится.
Base64URL: URL-безопасный близнец
В стандартном алфавите есть два символа, которые плохо ладят с URL. + в строке запроса традиционно читается как пробел, а / - разделитель пути, поэтому сырая Base64-строка в URL требует процентного экранирования и для того, и для другого, плюс заполнители =. Раздел 5 RFC 4648 определяет решение: алфавит, безопасный для URL и имён файлов, где + становится -, а / - _. Заполнители обычно тоже исчезают, потому что недостающий заполнитель можно вычислить по длине. RFC прямо говорит, что так нельзя называть простой Base64: это другое кодирование, обычно записывается как base64url.
На практике они различаются одной заменой - и в опасную сторону. Подайте строку base64url стандартному декодировщику, и пойдёт не так, потому что - и _ нет в стандартном алфавите: щадящий декодировщик отбросит их и вернёт более короткую, неверную байтовую строку - или, когда остаток слишком короткий, чтобы существовать сам по себе, ошибку, - а строгий отклонит все данные. Правильная хореография: вернуть - обратно в + и _ обратно в /, дописать недостающие заполнители и только потом декодировать. Именно этот диалект встречается в JSON Web Tokens (JWT), строках состояния OAuth и идентификаторах одного очень крупного видеохостинга.
Быстрый справочник
Прежде чем хвататься за инструмент, многое в строке можно прочесть самому. Несколько проверок подскажут, Base64 ли это вообще, и что в нём скрыто:
- Посмотрите на символы. Стандартный Base64 использует только A-Z, a-z, 0-9,
+и/; URL-безопасный близнец вместо них ставит-и_. Любой другой символ или случайный пробел означают, что это не чистый Base64. - Проверьте заполнители. Знаки
=, если они есть, стоят только в самом конце, и их не больше двух. Заполнитель посередине строки - красный флаг. - Посчитайте длину. С заполнителями длина всегда кратна 4. Без заполнителей деление длины на 4 даёт остаток 0, 2 или 3. Остаток 1 невозможен, потому что один символ несёт только 6 бит, а байту нужно 8.
- Оцените размер. Каждая группа из 4 символов несёт 3 байта, минус один байт за каждый знак
=. Так чтоZm9vYmFy- восемь символов без заполнителей - это 6 байтов, аZm9vYg==- восемь символов с двумя заполнителями - это 4.
Последний полевой трюк, и самый полезный. Кодировщик обязан обнулять биты заполнения, но щадящий декодировщик их не проверяет. Данные Zg== декодируются в единственный байт f, и Zh== тоже: младшие биты последнего символа в обоих случаях - заполняющие, поэтому оба обозначают один и тот же байт. Стандарт называет версию с нулевыми битами канонической формой, и она позволяет строгим декодировщикам отклонять другую. Две строки - одни данные. Если две системы не согласны насчёт значения Base64, биты заполнения - хорошее место, где стоит начать искать.
Чем Base64 не является
- Не шифрование. Ни ключа, ни секрета; любой может превратить Base64-строку обратно в байты за секунду. RFC даже упоминает реальные случаи, когда люди сообщали об обмене по протоколу, где присутствовал «закодированный» пароль, и были уверены, что кодирование его скрывает. Если данные чувствительные, защитите их настоящим шифрованием до кодирования, а не после.
- Не сжатие. Наоборот: результат примерно на 33 процента больше входа, а после добавления переносов строк и того больше. Base64 покупает вам текстовую безопасность и берёт за неё размером.
- Не набор символов. Base64 перемещает байты, а не буквы. Ему неизвестно и всё равно, являются ли эти байты текстом UTF-8, устаревшей однобайтной кодировкой или JPEG. Вопрос «какая это кодировка?» живёт до кодирования и после декодирования, но никогда внутри него.
- Не единое кодирование. За названием стоит целое семейство: стандартный алфавит, URL-безопасный близнец, данные, обёртые по 76 или 64 символа, варианты без заполнителей и несколько эксцентриков (IMAP, например, при кодировании международных имён почтовых ящиков использует запятую вместо
/из алфавита). Когда две системы не согласны по данным, виной обычно оказывается разница в диалектах.
Мелкий шрифт
Первоисточники краткие и читаются легко. RFC 4648, Кодирования данных Base16, Base32 и Base64 (2006), - действующий стандарт: оба алфавита, правила заполнения и переноса строк, правила строгости и набор официальных тестовых векторов, вроде превращения foo в Zm9v, по которым реализации проверяют сами себя. За ним стоит RFC 2045, спецификация MIME 1996 года, откуда взялись правило строки в 76 символов и терпимость к чужим символам, и RFC 1421, устаревшая спецификация Privacy Enhanced Mail, начавшая семейство со строк по 64 символа. Более ранняя попытка унификации, RFC 3548, была заменена RFC 4648.
В этом вся история: 64 символа, три байта на входе и четыре символа на выходе, = для завершения хвоста и идеальный круг. Любой инструмент, библиотека или онлайн-конвертер, с которым вы когда-либо столкнётесь, - лишь дверь в этот мир. Как только вы научитесь смотреть на Base64-строку и видеть стоящие за ней байты, формат больше не будет вас удивлять. И когда вы будете готовы написать декодировщик самостоятельно, статьи о языках программирования чуть ниже этого раздела отдадут вам те же 64 символа в виде рабочего кода: по одному полному руководству на каждый язык.