Почему мы используем Base64?

Википедия говорит, что

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

Но разве данные не всегда хранятся / передаются в двоичном виде, потому что память, которую наши машины хранят в двоичном виде, зависит только от того, как вы ее интерпретируете? Таким образом, независимо от того, кодируете ли вы битовую комбинацию 010011010110000101101110 как Man в ASCII или как TWFu в Base64, вы в конечном итоге собираетесь сохранить ту же битовую комбинацию.

Если окончательное кодирование выражается в единицах нулей и единиц, и каждая машина и носитель могут с ними справиться, какое значение имеет представление данных в виде ASCII или Base64?

Что означает «носитель, предназначенный для обработки с текстовыми данными "? Они могут иметь дело с бинарным => они могут иметь дело с чем угодно.


Спасибо всем, я думаю, теперь я понимаю.

Когда мы пересылаем данные, мы не можем быть уверены, что данные будут интерпретированы в том же формате, в котором мы намеревались. Итак, мы отправляем данные, закодированные в каком-то формате (например, Base64), который понимают обе стороны. Таким образом, даже если отправитель и получатель интерпретируют одни и те же вещи по-разному, но поскольку они согласны с кодированным форматом, данные не будут интерпретироваться неправильно.

Из Пример Mark Byers

Если я хочу отправить

Hello
world!

Один из способов - отправить его в ASCII, как

72 101 108 108 111 10 119 111 114 108 100 33

, но байт 10 может неправильно интерпретироваться как символ новой строки на другом конце. Таким образом, мы используем подмножество ASCII для его кодирования следующим образом

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

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

246
задан mega6382 11 September 2017 в 00:02
поделиться

10 ответов

Ваша первая ошибка состоит в том, что вы думаете, что кодировка ASCII и кодировка Base64 взаимозаменяемы. Они не. Их используют для разных целей.

  • Когда вы кодируете текст в ASCII, вы начинаете с текстовой строки и конвертируете ее в последовательность байтов.
  • Когда вы кодируете данные в Base64, вы начинаете с последовательности байтов и конвертируете ее в текстовую строку.

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


Компьютеры обмениваются данными в двоичном формате - нули и единицы - но люди, как правило, хотят обмениваться данными с более богатыми формами данных, такими как текст или изображения. Чтобы передать эти данные между компьютерами, они сначала должны быть закодированы в 0 и 1, отправлены, а затем снова декодированы. Возьмем, к примеру, текст - есть много разных способов выполнить эту кодировку. Было бы намного проще, если бы мы все могли договориться о единой кодировке, но, к сожалению, это не так.

Первоначально было создано множество различных кодировок (например, Код Бодо ), в которых использовалось разное количество бит на символ, пока, наконец, ASCII не стал стандартом с 7 битами на символ. Однако большинство компьютеров хранят двоичные данные в байтах, состоящих из 8 бит каждый, поэтому ASCII не подходит для передачи этого типа данных.Некоторые системы даже стирают самый старший бит. Кроме того, различие в кодировке окончания строки в разных системах означает, что символы ASCII 10 и 13 также иногда изменялись.

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

Для надежной отправки текста вы можете сначала закодировать в байты, используя кодировку текста по вашему выбору (например, UTF-8), а затем , а затем Base64 закодировать полученные двоичные данные в текстовая строка, которую можно безопасно отправлять, в кодировке ASCII. Получатель должен будет отменить этот процесс, чтобы восстановить исходное сообщение. Это, конечно, требует, чтобы получатель знал, какие кодировки использовались, и эту информацию часто нужно отправлять отдельно.

Исторически он использовался для кодирования двоичных данных в сообщениях электронной почты, где сервер электронной почты мог изменять окончания строк. Более современный пример - использование кодировки Base64 для встраивания данных изображения непосредственно в исходный код HTML . Здесь необходимо закодировать данные, чтобы символы типа «<» и «>» не интерпретировались как теги.


Вот рабочий пример:

Я хочу отправить текстовое сообщение с двумя строками

Hello
world!

Если я отправлю его как ASCII (или UTF-8), оно будет выглядеть так:

72 101 108 108 111 10 119 111 114 108 100 33

Байт 10 - это повреждены в некоторых системах, поэтому мы можем кодировать эти байты по базе 64 как строку Base64:

SGVsbG8sCndvcmxkIQ==

Что при кодировании с использованием ASCII выглядит следующим образом:

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

Все байты здесь известны как безопасные байты, поэтому вероятность того, что какая-либо система испортит это сообщение.Я могу отправить это вместо своего исходного сообщения и позволить получателю отменить процесс, чтобы восстановить исходное сообщение.

260
ответ дан 23 November 2019 в 03:04
поделиться

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

  • Новые строки обычно преобразуются в текстовом режиме.
  • Нужно быть осторожным, чтобы не рассматривать байт NUL как конец текстовой строки, что слишком легко сделать в любой программе с линией C.
5
ответ дан 23 November 2019 в 03:04
поделиться

Что означает «носители, которые предназначены для работы с текстовыми данными »?

Эти протоколы были разработаны для обработки текста (часто только английский текст) вместо двоичных данных (например, изображений .png и .jpg).

Они могут иметь дело с двоичными => они могут заниматься чем угодно.

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

  • Байты 0x0A и 0x0D, используемые для окончаний строк, которые различаются в зависимости от платформы.
  • Другие управляющие символы, такие как 0x00 (NULL = признак конца строки C), 0x03 (КОНЕЦ ТЕКСТА), 0x04 (КОНЕЦ ПЕРЕДАЧИ) или 0x1A (конец файла DOS), которые могут преждевременно сигнализировать об окончании данных.
  • Байт больше 0x7F (если протокол был разработан для ASCII).
  • Последовательности байтов, недопустимые в кодировке UTF-8.

Таким образом, вы не можете просто отправлять двоичные данные по текстовому протоколу. Вы ограничены байтами, которые представляют собой непробельные неконтролирующие символы ASCII, из которых 94. Причина, по которой был выбран Base 64, заключалась в том, что быстрее работать с степенями двойки, а 64 - самый большой, который работает .

Один вопрос. Как так системы до сих пор не согласны с общим метод кодирования, подобный столь распространенному UTF-8?

По крайней мере, в Интернете они есть. Большинство сайтов используют UTF-8 .

Проблема на Западе в том, что существует много старого программного обеспечения, которое считает, что 1 байт = 1 символ, и не может работать с UTF-8.

Проблема на Востоке заключается в их привязке к кодировкам вроде GB2312 и Shift_JIS.

И тот факт, что Microsoft, похоже, все еще не преодолела неправильный выбор кодировки UTF. Если вы хотите использовать Windows API или библиотеку времени выполнения Microsoft C, вы ограничены UTF-16 или кодировкой ANSI локали. Это затрудняет использование UTF-8, потому что вам все время приходится конвертировать.

6
ответ дан 23 November 2019 в 03:04
поделиться

Почему бы не взглянуть на RFC, который в настоящее время определяет Base64 ?

Базовое кодирование данных используется в много ситуаций для хранения или передачи
данные в средах, которые, возможно, для унаследованные причины ограничены Данные US-ASCII [1]. Базовая кодировка может также использоваться в новых приложениях которые не имеют устаревших ограничений, просто потому, что это делает возможным манипулировать объектами с текстом редакторы.

В прошлом разные приложения были разные требования и таким образом иногда реализуется база кодировки в немного разных способами. Сегодня спецификации протокола иногда используют базовые кодировки в вообще и base64 в частности, без точного описания или ссылка. Многоцелевая интернет-почта Расширения (MIME) [4] часто используются в качестве ссылки для base64 без учитывая последствия для перенос строк или не алфавит символы. Цель этого спецификация заключается в установлении общих алфавит и кодировка соображения. Надеюсь, это будет уменьшить двусмысленность в других документы, ведущие к лучшему совместимость.

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

37
ответ дан 23 November 2019 в 03:04
поделиться

Носители, предназначенные для текстовых данных, конечно, в конечном итоге также являются двоичными, но текстовые носители часто используют определенные двоичные значения для управляющих символов. Кроме того, текстовые носители могут отклонять определенные двоичные значения как нетекстовые.

Кодировка Base64 кодирует двоичные данные как значения, которые могут быть интерпретированы только как текст на текстовых носителях, и не содержит каких-либо специальных символов и / или управляющих символов, так что данные будут сохранены и на текстовых носителях.

26
ответ дан 23 November 2019 в 03:04
поделиться

Кодирование двоичных данных в XML

Предположим, вы хотите встроить пару изображений в XML-документ. Изображения представляют собой двоичные данные, а документ XML - текст. Но XML не может обрабатывать встроенные двоичные данные. Так как же это сделать?

Один из вариантов - закодировать изображения в base64, превратив двоичные данные в текст, который может обрабатывать XML.

Вместо:

<images>
  <image name="Sally">{binary gibberish that breaks XML parsers}</image>
  <image name="Bobby">{binary gibberish that breaks XML parsers}</image>
</images>

вы выполните:

<images>
  <image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
  <image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
</images>

И синтаксический анализатор XML сможет правильно проанализировать XML-документ и извлечь данные изображения.

57
ответ дан 23 November 2019 в 03:04
поделиться

Один из примеров, когда я нашел это удобным, - это попытка встроить двоичные данные в XML . Некоторые двоичные данные неправильно интерпретировались парсером SAX, потому что эти данные могли быть буквально любыми, включая специальные символы XML. Кодирование данных в кодировке Base64 на передающей стороне и их декодирование на принимающей стороне устранило эту проблему.

12
ответ дан 23 November 2019 в 03:04
поделиться

Большинство компьютеров хранят данные в 8-битном двоичном формате, но это не является обязательным требованием. Некоторые машины и средства передачи могут обрабатывать только 7 бит (или даже меньше) за раз. Такой носитель будет интерпретировать поток в количестве, кратном 7 битам, поэтому, если вы отправите 8-битные данные, вы не получите то, что ожидаете на другой стороне. Base-64 - это всего лишь один из способов решения этой проблемы: вы кодируете ввод в 6-битный формат, отправляете его через свой носитель и декодируете обратно в 8-битный формат на принимающей стороне.

10
ответ дан 23 November 2019 в 03:04
поделиться

Это больше, чем носитель проверяет строковую кодировку, поэтому мы хотим убедиться, что данные приемлемы для обрабатывающего приложения (и не содержат, например, двоичной последовательности, представляющей EOL)

Представьте, что вы хотите отправить двоичные данные в электронном письме с кодировкой UTF-8 - электронное письмо может отображаться некорректно, если поток единиц и нулей создает последовательность , которая не является допустимой Unicode в UTF-8. кодирование.

То же самое происходит с URL-адресами, когда мы хотим закодировать символы, недопустимые для URL-адреса, в самом URL-адресе:

http://www.foo.com/hello мой друг -> http://www.foo.com/hello%20my%20friend

Это потому, что мы хотим отправить пробел над системой, которая будет думать, что это место дурно пахнет.

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

В вашем примере man может быть действительным ASCII в первой форме; но часто вы можете захотеть передать значения, которые являются случайными двоичными (например, отправив изображение по электронной почте):

MIME-Version: 1.0
Content-Description: "Кодирование в формате Base64 a.gif"
Тип содержимого: изображение / gif; name = "a.gif"
Кодирование передачи содержимого: Base64
Content-Disposition: вложение; filename = "a.gif"

Здесь мы видим, что изображение GIF закодировано в base64 как фрагмент электронного письма. Почтовый клиент читает заголовки и декодирует их.Благодаря кодировке мы можем быть уверены, что GIF не содержит ничего, что может быть интерпретировано как протокол, и избегаем вставки данных, которые SMTP или POP могут счесть важными.

17
ответ дан 23 November 2019 в 03:04
поделиться

Что означает «носитель, предназначенный для работы с текстовыми данными»?

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

3
ответ дан 23 November 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: