stringtranslate.com

База64

В компьютерном программировании Base64 представляет собой группу схем кодирования двоичного текста в текст , которые преобразуют двоичные данные в последовательность печатных символов, ограниченную набором из 64 уникальных символов. Точнее, исходные двоичные данные берутся по 6 бит за раз, затем эта группа из 6 бит сопоставляется с одним из 64 уникальных символов.

Как и все схемы кодирования двоичного текста, Base64 предназначен для передачи данных, хранящихся в двоичных форматах, по каналам, которые надежно поддерживают только текстовый контент. Base64 особенно распространен во Всемирной паутине [1] , где одним из его применений является возможность встраивания файлов изображений или других двоичных ресурсов в текстовые ресурсы, такие как файлы HTML и CSS . [2]

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

Кодирование Base64 вызывает накладные расходы в размере 33–37% относительно размера исходных двоичных данных (33% за счет самого кодирования; до 4% больше за счет вставленных разрывов строк).

Дизайн

Конкретный набор из 64 символов, выбранный для представления 64-значных значений базы, варьируется в зависимости от реализации. Общая стратегия состоит в том, чтобы выбрать 64 символа, которые являются общими для большинства кодировок и которые также можно распечатать. Эта комбинация исключает возможность изменения данных при передаче через информационные системы, такие как электронная почта, которые традиционно не были 8-битными . [3] Например, реализация MIMEA Base64 использует – Z, azи 09для первых 62 значений. Другие варианты разделяют это свойство, но отличаются символами, выбранными для двух последних значений; пример — UTF-7 .

Самые ранние экземпляры этого типа кодирования были созданы для коммутируемой связи между системами, работающими под управлением одной и той же ОС — например, uuencode для UNIX и BinHex для TRS-80 (позже адаптированного для Macintosh ) — и, следовательно, можно было сделать больше предположений о какие символы можно было безопасно использовать. Например, uuencode использует прописные буквы, цифры и множество знаков препинания, но не строчные. [4] [5] [6] [3]

Таблица Base64 из RFC 4648

Это алфавит Base64, определенный в RFC 4648 §4. См. также сводку вариантов (ниже).

Примеры

В приведенном ниже примере для простоты используется текст ASCII , но это не типичный вариант использования, поскольку его уже можно безопасно переносить во все системы, поддерживающие Base64. Более типичное использование — кодирование двоичных данных (например, изображения); результирующие данные Base64 будут содержать только 64 различных символа ASCII, каждый из которых можно надежно передавать между системами, что может привести к повреждению необработанных исходных байтов.

Вот известная идиома из распределенных вычислений :

Много рук делают работу легче.

Когда кавычка (без завершающих пробелов) кодируется в Base64, она представляется как последовательность байтов 8-битных символов ASCII , закодированных в схеме MIME Base64 следующим образом (переводы строк и пробелы могут присутствовать где угодно, но должны быть игнорируется при декодировании):

TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu

В приведенной выше цитате закодированное значение ManTWFu . Закодированные в ASCII символы M , a и n сохраняются как байтовые значения 77, 97и 110, которые представляют собой 8-битные двоичные значения 01001101, 01100001и 01101110. Эти три значения объединяются в 24-битную строку, в результате чего получается 010011010110000101101110. Группы по 6 бит (6 бит имеют максимум 2 6  = 64 различных двоичных значения) преобразуются в отдельные числа от начала до конца (в данном случае в 24-битной строке четыре числа), которые затем преобразуются в соответствующие им значения символов Base64.

Как показано в этом примере, кодировка Base64 преобразует три октета в четыре закодированных символа.

=можно добавить символы заполнения, чтобы последний закодированный блок содержал четыре символа Base64.

Преобразование шестнадцатеричного числа в восьмеричное полезно для преобразования между двоичным кодом и Base64. Такое преобразование доступно как для продвинутых калькуляторов, так и для языков программирования. Например, шестнадцатеричное представление 24 приведенных выше битов — 4D616E. Восьмеричное представление — 23260556. Эти 8 восьмеричных цифр можно разделить на пары ( 23 26 05 56 ), и каждая пара преобразуется в десятичное число, чтобы получить 19 22 05 46 . Если использовать эти четыре десятичных числа в качестве индексов алфавита Base64, соответствующие символы ASCII будут TWFu .

Если имеется только два значащих входных октета (например, «Ма») или когда последняя входная группа содержит только два октета, все 16 бит будут захвачены в первых трех цифрах Base64 (18 бит); два младших бита последнего 6-битного блока, несущего контент, окажутся равными нулю и будут отброшены при декодировании (вместе с последующим =символом заполнения):

Если имеется только один значащий входной октет (например, «M») или когда последняя входная группа содержит только один октет, все 8 бит будут захвачены в первых двух цифрах Base64 (12 бит); четыре младших бита последнего 6-битного блока, несущего контент, окажутся равными нулю и отброшены при декодировании (вместе с двумя последующими =символами заполнения):

Существуют также интерактивные инструменты для пошаговой визуализации кодировки от обычного текста до base64. [7]

Заполнение вывода

Поскольку Base64 представляет собой шестибитную кодировку, а декодированные значения делятся на 8-битные октеты, каждые четыре символа текста, закодированного в Base64 (4 секстета = 4 × 6 = 24 бита), представляют собой три октета незакодированного текста или данных ( 3 октета = 3 × 8 = 24 бита). Это означает, что если длина некодированного ввода не кратна трем, к закодированному выводу необходимо добавить дополнение, чтобы его длина была кратна четырем. Символ заполнения — =, который указывает, что для полного кодирования ввода дополнительные биты не требуются. (Это отличается от A, что означает, что все остальные биты являются нулями.) Пример ниже иллюстрирует, как усечение входных данных приведенной выше кавычки меняет выходное заполнение:

Символ заполнения не важен для декодирования, поскольку количество пропущенных байтов можно определить по длине закодированного текста. В некоторых реализациях символ заполнения является обязательным, а в других он не используется. Исключением, когда требуются символы заполнения, является объединение нескольких файлов в кодировке Base64.

Декодирование Base64 с заполнением

При декодировании текста Base64 четыре символа обычно преобразуются обратно в три байта. Единственным исключением являются случаи, когда существуют символы заполнения. Один =указывает, что четыре символа будут декодироваться только в два байта, тогда как ==указывает, что четыре символа будут декодироваться только в один байт. Например:

Другой способ интерпретации символа заполнения — рассматривать его как инструкцию по удалению двух конечных битов из битовой строки каждый раз, когда =встречается a. Например, при декодировании ` bGlnaHQg dw== ` мы преобразуем каждый символ (кроме конечных вхождений ) в соответствующее 6-битное представление, а затем отбрасываем 2 завершающих бита для первого и еще 2 завершающих бита для другого . В этом случае мы получили бы 6 битов из , и еще 6 битов из строки битов длиной 12, но поскольку мы удаляем по 2 бита для каждого (всего 4 бита), в итоге получается 8 бит ( 1 байт) при декодировании.===dw=dw==

Декодирование Base64 без заполнения

Без заполнения после обычного декодирования четырех символов в три байта снова и снова может остаться менее четырех закодированных символов. В такой ситуации могут остаться только два-три персонажа. Один оставшийся закодированный символ невозможен, поскольку один символ Base64 содержит только 6 бит, а для создания байта требуется 8 бит, поэтому требуется минимум два символа Base64: первый символ составляет 6 бит, а второй символ вносит свои первые 2 бита. Например:

Декодирование без заполнения не выполняется согласованно среди декодеров. Кроме того, разрешение бесконтактного декодирования по определению позволяет декодировать несколько строк в один и тот же набор байтов, что может представлять угрозу безопасности. [8]

Реализации и история

Сводная таблица вариантов

Реализации могут иметь некоторые ограничения на алфавит, используемый для представления некоторых битовых комбинаций. Это особенно касается двух последних символов, используемых в алфавите в позициях 62 и 63, а также символа, используемого для заполнения (который может быть обязательным в некоторых протоколах или удаленным в других). В таблице ниже обобщены эти известные варианты и приведены ссылки на подразделы ниже.

  1. ^ ab Этот вариант предназначен для предоставления общих функций, специализация которых не требуется в реализациях, обеспечивая надежное проектирование. Это особенно актуально в свете кодировок и ограничений отдельных строк, которые не учитывались, когда предыдущие стандарты были адаптированы для использования в других местах. Таким образом, указанные здесь функции могут быть переопределены.

Почта с повышенной конфиденциальностью

Первое известное стандартизированное использование кодировки, которая теперь называется MIME Base64, было в протоколе электронной почты с улучшенной конфиденциальностью (PEM), предложенном RFC  989 в 1987 году. PEM определяет схему «кодирования для печати», которая использует кодировку Base64 для преобразования произвольной последовательности октеты в формат, который можно выразить короткими строками из 6-битных символов, как того требуют протоколы передачи, такие как SMTP . [9]

Текущая версия PEM (указанная в RFC  1421) использует 64-значный алфавит, состоящий из латинских букв верхнего и нижнего регистра ( – , – ), цифр ( – ) и символов и . Символ также используется в качестве суффикса заполнения. [4] В исходной спецификации RFC  989 этот символ дополнительно использовался для разграничения закодированных, но незашифрованных данных в выходном потоке.AZaz09+/=*

Чтобы преобразовать данные в кодировку PEM для печати, первый байт помещается в восемь старших бит 24-битного буфера , следующий — в средние восемь, а третий — в восемь младших битов. Если для кодирования осталось менее трех байтов (или всего), оставшиеся биты буфера будут равны нулю. Затем буфер используется по шесть битов, начиная со старшего, в качестве индексов в строке: " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", и выводится указанный символ.

Процесс повторяется с оставшимися данными до тех пор, пока не останется менее четырех октетов. Если остаются три октета, они обрабатываются нормально. Если для кодирования осталось менее трех октетов (24 бита), входные данные дополняются справа нулевыми битами, чтобы сформировать целое число, кратное шести битам.

Если после кодирования незаполненных данных два октета 24-битного буфера заполнены нулями, =к выходным данным добавляются два символа; если один октет 24-битного буфера заполнен дополненными нулями, =добавляется один символ. Это сигнализирует декодеру, что нулевые биты, добавленные в результате заполнения, должны быть исключены из восстановленных данных. Это также гарантирует, что длина закодированного вывода будет кратна 4 байтам.

PEM требует, чтобы все закодированные строки содержали ровно 64 печатных символа, за исключением последней строки, которая может содержать меньше печатных символов. Строки разделяются пробелами в соответствии с местными (зависящими от платформы) соглашениями.

МИМ

В спецификации MIME (многоцелевые расширения почты Интернета) Base64 указан как одна из двух схем кодирования двоичного текста в текст (вторая — Quote-printable ). [5] Кодировка MIME Base64 основана на версии PEM из RFC  1421: она использует тот же 64-символьный алфавит и механизм кодирования, что и PEM, и использует символ для заполнения вывода таким же образом, как описано в RFC  2045.=

MIME не определяет фиксированную длину строк в кодировке Base64, но указывает максимальную длину строки в 76 символов. Кроме того, он указывает, что любой символ, выходящий за пределы стандартного набора из 64 символов кодировки (например, последовательности CRLF), должен игнорироваться совместимым декодером, хотя в большинстве реализаций для разделения закодированных строк используется пара новой строки CR/LF .

Таким образом, фактическая длина MIME-совместимых двоичных данных в кодировке Base64 обычно составляет около 137% от исходной длины данных ( 43 × 7876 ), хотя для очень коротких сообщений накладные расходы могут быть намного выше из-за накладных расходов на заголовки. Грубо говоря, конечный размер двоичных данных в кодировке Base64 равен 1,37 исходному размеру данных + 814 байт (для заголовков). Размер декодированных данных можно аппроксимировать этой формулой:

байт = (длина_строки(закодированная_строка) - 814) / 1,37

UTF-7

UTF-7 , впервые описанный в RFC  1642, который позже был заменен RFC  2152, представил систему под названием модифицированный Base64 . Эта схема кодирования данных используется для кодирования UTF-16 как символов ASCII для использования в 7-битных транспортных протоколах, таких как SMTP . Это вариант кодировки Base64, используемой в MIME. [10] [11]

Алфавит «Модифицированный Base64» состоит из алфавита MIME Base64, но не использует =символ заполнения «». UTF-7 предназначен для использования в заголовках сообщений (определенных в RFC  2047), а символ " " зарезервирован в этом контексте как escape-символ для кодировки "quoted-printable". Модифицированный Base64 просто опускает заполнение и заканчивается сразу после последней цифры Base64, содержащей полезные биты, оставляя до трех неиспользуемых битов в последней цифре Base64.=

OpenPGP

OpenPGP , описанный в RFC  4880, описывает кодировку Radix-64 , также известную как « броня ASCII ». Radix-64 идентична кодировке Base64, описанной MIME, с добавлением дополнительной 24-битной CRC . Контрольная сумма вычисляется на входных данных перед кодированием; контрольная сумма затем кодируется с помощью того же алгоритма Base64 и добавляется к закодированным выходным данным с префиксом символа " " в качестве разделителя. [12]=

RFC 3548

RFC  3548, озаглавленный «Кодировки данных Base16, Base32 и Base64» , представляет собой информационный (ненормативный) документ, в котором делается попытка унифицировать спецификации RFC  1421 и RFC  2045 кодировок Base64, кодировок с альтернативным алфавитом и Base32 (который редко используется). используется) и кодировки Base16.

Если реализации не написаны в соответствии со спецификацией, которая ссылается на RFC  3548 и конкретно не требует иного, RFC 3548 запрещает реализациям генерировать сообщения, содержащие символы вне алфавита кодировки или без заполнения, а также заявляет, что реализации декодера должны отклонять данные, содержащие символы вне кодировки. алфавит. [6]

RFC 4648

Этот RFC устарел RFC 3548 и ориентирован на Base64/32/16:

В этом документе описаны широко используемые схемы кодирования Base64, Base32 и Base16. В нем также обсуждается использование перевода строки в закодированных данных, использование заполнения в закодированных данных, использование символов, не являющихся алфавитами, в закодированных данных, использование различных алфавитов кодирования и канонических кодировок.

URL-приложения

Кодирование Base64 может оказаться полезным, когда в среде HTTP используется довольно длинная идентификационная информация. Например, платформа сохранения базы данных для объектов Java может использовать кодировку Base64 для кодирования относительно большого уникального идентификатора (обычно 128-битные UUID ) в строку для использования в качестве параметра HTTP в формах HTTP или URL- адресах HTTP GET . Кроме того, многим приложениям необходимо кодировать двоичные данные таким образом, чтобы их было удобно включать в URL-адреса, в том числе в скрытые поля веб-форм, а Base64 — это удобная кодировка для их компактного отображения.

Использование стандартного Base64 в URL-адресе требует кодирования символов ' +', ' /' и ' =' в специальные шестнадцатеричные последовательности с процентной кодировкой+ (' ' становится ' %2B', ' /' становится ' %2F' и ' =' становится ' %3D'), что делает строку неоправданно длиннее. .

По этой причине существуют модифицированные варианты Base64 для URL-адресов (например, base64url в RFC  4648), где символы ' ' и ' ' стандартного Base64 заменяются соответственно на ' ' и ' ', так что использование кодировщиков/декодеров URL-адресов больше не требуется. необходимо и не влияет на длину закодированного значения, оставляя ту же закодированную форму нетронутой для использования в реляционных базах данных, веб-формах и идентификаторах объектов в целом. Популярным сайтом, где можно использовать такие возможности, является YouTube . [13] Некоторые варианты позволяют или требуют опускать знаки заполнения ' ', чтобы их не путать с разделителями полей, или требуют, чтобы любое такое дополнение было закодировано в процентах. Некоторые библиотеки [ какие? ] будет кодировать ' ' в ' ', потенциально подвергая приложения атакам по относительному пути, когда имя папки закодировано из пользовательских данных. [ нужна цитата ]+/-_==.

Javascript (веб-API DOM)

Методы JavaScript atob()и btoa(), определенные в проекте спецификации HTML5, [14] обеспечивают функциональность кодирования и декодирования Base64 для веб-страниц. Метод btoa()выводит символы заполнения, но они не являются обязательными при вводе метода atob().

Другие приложения

Пример SVG, содержащего встроенные изображения JPEG, закодированные в Base64 [15]

Base64 можно использовать в различных контекстах:

Приложения, несовместимые с RFC 4648 Base64.

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

Одна из проблем с алфавитом RFC 4648 заключается в том, что когда отсортированный список строк в кодировке ASCII преобразуется с помощью Base64 и снова сортируется, порядок элементов меняется. Это связано с тем, что символ заполнения и символы в алфавите замены не упорядочены по значению символа ASCII (что можно увидеть, используя кнопки сортировки в следующей примерной таблице). Для решения этой проблемы используются такие алфавиты, как (без дополнений) B64 .

Смотрите также

Рекомендации

  1. ^ «Кодирование и декодирование Base64 – веб-API» . Веб-документы MDN. Архивировано из оригинала 11 ноября 2014 г.
  2. ^ «Когда кодировать изображения в формате Base64 (а когда нет)» . 28 августа 2011 г. Архивировано из оригинала 29 августа 2023 г.
  3. ^ ab Кодировки данных Base16, Base32 и Base64. IETF . Октябрь 2006 г. doi : 10.17487/RFC4648 . РФК 4648 . Проверено 18 марта 2010 г.
  4. ^ ab Повышение конфиденциальности для электронной почты в Интернете: Часть I: Процедуры шифрования и аутентификации сообщений. IETF . Февраль 1993 г. doi : 10.17487/RFC1421 . РФК 1421 . Проверено 18 марта 2010 г.
  5. ^ ab Многоцелевые расширения почты Интернета: (MIME) Часть первая: Формат тел интернет-сообщений. IETF . Ноябрь 1996 г. doi : 10.17487/RFC2045 . РФК 2045 . Проверено 18 марта 2010 г.
  6. ^ ab Кодировки данных Base16, Base32 и Base64. IETF . Июль 2003 г. doi : 10.17487/RFC3548 . РФК 3548 . Проверено 18 марта 2010 г.
  7. ^ «Интерактивный инструмент для визуализации кодировки» . base64decode.tech .
  8. ^ Халкиас, Константинос; Хацигианнис, Панайотис (30 мая 2022 г.). Податливость Base64 на практике (PDF) . ASIA CCS '22: ACM 2022 на Азиатской конференции по компьютерной и коммуникационной безопасности. стр. 1219–1221. дои : 10.1145/3488932.3527284.
  9. ^ Повышение конфиденциальности для электронной почты Интернета. IETF . Февраль 1987 г. doi : 10.17487/RFC0989 . РФК 989 . Проверено 18 марта 2010 г.
  10. ^ UTF-7 Формат преобразования Unicode, безопасный для почты. IETF . Июль 1994 г. doi : 10.17487/RFC1642 . РФК 1642 . Проверено 18 марта 2010 г.
  11. ^ UTF-7 Формат преобразования Unicode, безопасный для почты. IETF . Май 1997 г. doi : 10.17487/RFC2152 . РФК 2152 . Проверено 18 марта 2010 г.
  12. ^ Формат сообщения OpenPGP. IETF . Ноябрь 2007 г. doi : 10.17487/RFC4880 . РФК 4880 . Проверено 18 марта 2010 г.
  13. ^ «Вот почему на YouTube практически никогда не закончатся уникальные идентификаторы видео» . www.mentalfloss.com . 23 марта 2016 года . Проверено 27 декабря 2021 г.
  14. ^ «7.3. Служебные методы Base64» . Редакторский черновик HTML 5.2 . Консорциум Всемирной паутины . Проверено 2 января 2018 г.Введено набором изменений 5814, 01 февраля 2021 г.
  15. ^ <image xlink:href="data:image/jpeg;base64, JPEG contents encoded in Base64" ... />
  16. ^ "Редактировать скрипку" . jsfiddle.net .
  17. ^ «Стандарт GEDCOM, версия 5.5» . Homepages.rootsweb.ancestry.com . Проверено 21 июня 2012 г.
  18. ^ Провос, Нильс (13 февраля 1997 г.). "src/lib/libc/crypt/bcrypt.c r1.1" . Проверено 18 мая 2018 г.
  19. ^ «6PACK — протокол ПК «реального времени» для TNC» . Архивировано из оригинала 24 февраля 2012 г. Проверено 19 мая 2013 г.
  20. ^ "Арифметика оболочки" . Справочное руководство по Bash . Проверено 8 апреля 2020 г. В противном случае числа принимают форму [base#]n, где необязательная база — это десятичное число от 2 до 64, представляющее арифметическую базу, а n — число в этой базе.