Русский

Инструменты разработчика · Кодер и декодер Base64

Краткая история Base64: от uuencode и PEM до сегодняшнего алфавита

· Фон

base64 кодирование

Временная шкала от uuencode и PEM до MIME до RFC 4648 развития Base64
Оригинальная векторная иллюстрация ToolAcre

Алфавит Base64 — это окаменелость транспортных проблем 1980-х годов. Этот пост прослеживает путь от uuencode через Privacy-Enhanced Mail до MIME и RFC 4648 и объясняет каждый вариант дизайна.

Почему алфавит не состоит просто из 0–63 в каком-то очевидном порядке — вопрос, который возвращает нас на четыре десятилетия назад.

Base64 не выглядел полностью сформированным стандартом. Алфавит (A-Z, a-z, 0-9, +, /) представляет собой окаменелую запись десятилетий экспериментов по кодированию, каждый из которых пытается решить одну и ту же проблему: как представить двоичные данные в виде текста, который пережил электронную почту 1970-х и 1980-х годов, USENET и инструменты Unix. История охватывает uuencode на Unix, почта с улучшенной конфиденциальностью (RFC 1421) в 1993, MIME (RFC 2045) в 1996 и, наконец, RFC 4648 в 2006, объединяя все варианты.

Понимание этой истории объясняет, почему в алфавите присутствуют определенные символы и почему RFC оставил разработчикам определенный выбор. uuencode, сокращение от Unix-to-Unix encode, был первым инструментом, решившим проблему 7-битной транспортировки в Unix. Созданный в 1980, он закодировал каждый 3 bytes (24 bits) в 4 символов из 64-символьного алфавита. Алфавит uuencode был от ASCII 32 (пробел) до ASCII 95 (подчеркивание и другие знаки препинания), выбранных потому, что эти символы можно распечатать на любом терминале. Репозиторий демонстрирует реализованный в настоящее время алфавит, но не содержит архивных свидетельств о том, кто выбрал этот порядок или почему каждый персонаж победил. Поэтому заголовок сужается: нынешнюю планировку можно рассмотреть в точности, а мотивы и даты требуют первичных исторических документов, сюда не включенных.

Почему алфавит выглядит историческим — граница, которую этот репозиторий не документирует

Однако использование пробела в качестве символа кодировки проблематично: текстовые редакторы и почтовые системы обрезают конечные пробелы, искажая вывод. Алфавит не был идеальным, но он достаточно хорошо работал для передачи файлов между Unix. Почта с улучшенной конфиденциальностью (RFC 1421, 1992) была ранней попыткой стандартизировать зашифрованную электронную почту. Он включал собственную кодировку Base64 (RFC 1341 для MIME, которая RFC 1421 предшествовала спецификации, но отставала в принятии).

RFC 1421 Base64 использовал алфавит A-Z, a-z, 0-9, +, / (современный алфавит Base64) и переносил строки на 64 символов. В этом алфавите отсутствуют пробелы и другие проблемные символы; каждый символ однозначно печатается и не путается с контрольными кодами или вариациями национального набора символов. Длина строки 64 символов соответствовала ширине бумажных терминалов 1980-х годов и была практическим компромиссом для читаемости. Uuencode принадлежит окружающей истории, однако инструмент не читает и не записывает свой алфавит. Рассматривать его как взаимозаменяемый Base64 было бы ошибкой формата. Полезное сравнение здесь ограничено общей проблемой представления байтов печатными символами.

Более ранние кодировки как контекст, а не свидетельство реализации

RFC 1421 не получил широкого распространения для зашифрованной электронной почты, но его алфавит Base64 сохранился. MIME (многоцелевые расширения почты Интернета, RFC 2045, 1996) приняли алфавит RFC 1421 Base64, но изменили перенос строк с 64 на 76 символов. Причина была не техническая, а историческая: блоки PEM (Privacy-Enhanced Mail) содержали 64 символов, а MIME выбрал немного другой предел, чтобы избежать путаницы с PEM при автоматическом анализе.

MIME Base64 стал стандартом для вложений электронной почты и сегодня является наиболее широко используемым вариантом Base64. RFC 2045 также определяет другие значения Content-Transfer-Encoding (7bit, 8bit, quote-printable), предоставляя параметры почтовой системы в зависимости от типа контента. Выбор алфавита позволяет избежать символов, которые различаются между ASCII и EBCDIC (кодировка символов мейнфрейма IBM). Символы A-Z, a-z, 0-9, + и / одинаковы в обеих кодировках. Блоки в стиле PEM узнаваемы, поскольку метки окружают закодированный материал. ToolAcre может обрабатывать извлеченное тело Base64 после удаления этих меток. Он не может установить, какая архивная спецификация впервые использовала данное соглашение, и эта статья не претендует на то, что дерево исходного кода отвечает на этот вопрос.

Броня в стиле PEM как современный наблюдаемый формат, без указания истории происхождения.

Такие символы, как открывающая и закрывающая скобка, различаются между ASCII и EBCDIC, поэтому они были исключены. Это было важно в 1980-х и начале 1990-х годов, когда передача данных с мэйнфрейма на Unix была обычным явлением. В алфавите также отсутствуют обратная косая черта, одинарные и двойные кавычки, которые имеют особое значение в строках C и синтаксисе оболочки. Строку Base64 можно внедрить в программу C или сценарий оболочки, не экранируя почти каждый символ.

RFC 3548 (2006) объединяет кодировки Base64, base32 и base16. Он отметил, что MIME, PEM и другие приложения используют схожие концепции, но с разными правилами заполнения и алфавитами. RFC 4648 (2006, опубликованный вместе с RFC 3548) — это текущий стандарт, определяющий пять семейств кодирования с тестовыми векторами для каждого. RFC также записывает историю: какие документы определяли какие кодировки, что менялось между версиями и почему был сделан такой выбор. Опция переноса символов 76 кодера и удаление пробелов декодера делают образцы в форме MIME тестируемыми. Эти факты реализации не отражают полную историю почтовых стандартов. Они показывают современное поведение совместимости, которое ридеры могут воспроизводить непосредственно в панели и тестах.

Обертка в стиле MIME в качестве опции кодировщика без восстановления истории стандартов

Большинство разработчиков сталкиваются только с base64 и base64url в RFC 4648; история документирована для тех, кому необходимо реализовать более старые варианты. Base64url (RFC 4648 раздел 5) заменяет плюс на тире, а косую черту на подчеркивание, чтобы избежать зарезервированных символов URL. Строка base64, содержащая + и /, должна быть закодирована в процентах в URL (%2B и %2F); base64url позволяет избежать этого.

JWT (JSON веб-токен) использует base64url без заполнения. Некоторые приложения используют base64url с дополнением. RFC определяет оба варианта; Выбор зависит от приложения. Именно из-за этого различия декодер JWT и декодер Base64 электронной почты могут выдавать разные выходные данные для одной и той же входной строки (один ожидает base64url, другой — base64). Алфавит, правила заполнения и перенос строк возникли из практических ограничений реальных систем. Переносимость лучше всего рассматривать как ограничение транспортных алфавитов, а не как проверенную биографию каждого символа. Буквы и цифры остаются визуально знакомыми в распространенных текстовых системах, а окончательная пунктуация отличается в URL-безопасном режиме. Точное историческое обоснование выбора опускается без первичных доказательств.

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

Набор символов 64 был выбран для обеспечения возможности представления в разных кодировках; алфавит был исправлен RFC 1341 и 1421 и MIME; правило заполнения получено из выравнивания 3 байт; а перенос строк возник из-за ограничений на транспортировку электронной почты. Реализация, игнорирующая эту историю, может изобрести новую кодировку или забыть о крайнем случае. Тестовые векторы RFC 4648 (foobar создает Zm9vYmFy) — это способ убедиться, что реализация соответствует стандарту.

Современные альтернативы, такие как base85 (используемые в некоторых контекстах), существуют, но base64 остается доминирующим из-за исторического импульса и потому, что он достаточно хорош. Base64 — не самая компактная кодировка (base85 и base91 более плотные), но она простая, универсальная и проверенная. Что можно твердо сказать, так это текущую пару алфавитов: стандартный заканчивается плюсом и косой чертой; URL — безопасная замена дефиса и подчеркивания. Заполнение и упаковка — это отдельные параметры. Тесты охватывают оба режима и отсутствующие дополнения, предоставляя воспроизводимые доказательства текущего поведения, а не предполагаемую хронологию.

Что репозиторий доказывает о текущих стандартных и URL-безопасных алфавитах

Накладные расходы на размер 33 в процентах приемлемы для большинства применений. Алфавит стабилен во всех реализациях. RFC достаточно ясен, поэтому отклонения обычно являются преднамеренными (например, пропуск заполнения или обработка пробелов), а не случайным недоразумением.

Понимание истории Base64 объясняет, почему он выглядит именно так. Символы плюс и косая черта были выбраны намеренно, чтобы избежать двусмысленности в различных кодировках символов. Правило заполнения взято из 3-байтовой группы. Base85 и Ascii85 используют разные размеры групп и алфавиты и находятся за пределами реализации. Упоминание о них не делает эту страницу конвертером для них. Для сравнения их плотности или истории потребуются источники и тестовые векторы, выходящие за рамки файлов Base64, рассмотренных для этого модуля.

Вывод: каждый символ был выбран не просто так — как кодировщик и декодер Base64 реализует стандартный алфавит, который получился в результате

Перенос строк пришел из электронной почты. Каждое решение было принято для решения реальной проблемы с реальными системами. Сегодня Base64 в основном используется в контекстах (JWT, API, URI данных), где история не имеет значения, но правила алфавита и заполнения наследуются от MIME и PEM через RFC 4648.

Однократное чтение RFC и кодирование тестовой строки с помощью инструмента кодирования и декодера Base64 связывает настоящий стандарт с его историческими корнями. Результирующий стандартный алфавит виден всякий раз, когда входные данные достигают индексов шестьдесят два или шестьдесят три. Используйте образец, который создает эти позиции, переключите безопасный режим URL и сравните только измененную пунктуацию. Этот эксперимент демонстрирует сегодняшний формат, не опираясь на ничем не подтвержденную историю о его изобретении.