stringtranslate.com

Base64

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

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

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

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

Дизайн

Конкретный набор из 64 символов, выбранный для представления 64-значных значений для базы, различается в зависимости от реализации. Общая стратегия заключается в выборе 64 символов, которые являются общими для большинства кодировок и которые также являются печатаемыми. Такая комбинация делает маловероятным изменение данных при передаче через информационные системы, такие как электронная почта, которые традиционно не были 8-битными чистыми . [3] Например, реализация Base64 MIME использует –A , Za, zи 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 , закодированных в схеме Base64 MIME следующим образом (символы новой строки и пробелы могут присутствовать в любом месте, но при декодировании их следует игнорировать):

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 .

Если имеется только два значимых входных октета (например, «Ma») или когда последняя входная группа содержит только два октета, все 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 четыре символа обычно преобразуются обратно в три байта. Исключение составляют только символы заполнения. Один =указывает, что четыре символа будут декодированы только в два байта, а ==указывает, что четыре символа будут декодированы только в один байт. Например:

Другой способ интерпретации символа заполнения — рассматривать его как инструкцию отбрасывать 2 конечных бита из битовой строки каждый раз, когда =встречается 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, было в протоколе Privacy-enhanced Electronic Mail (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

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

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

Таким образом, фактическая длина двоичных данных, закодированных в Base64 и совместимых с MIME, обычно составляет около 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]

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

OpenPGP

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

RFC3548

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

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

Запрос на изменение 4648

RFC  4648 устарел 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] Некоторые варианты разрешают или требуют пропускать знаки заполнения ' ', чтобы избежать их путаницы с разделителями полей, или требуют, чтобы любое такое заполнение было закодировано процентами. Некоторые библиотеки [ which? ] будут кодировать ' ' в ' ', потенциально подвергая приложения атакам относительного пути, когда имя папки кодируется из пользовательских данных. [ необходима цитата ]+/-_==.

Javascript (DOM Web API)

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

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

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

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

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

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

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

Ссылки

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