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

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

229 голосов
/ 21 августа 2010

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

Схемы кодирования 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

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

Ответы [ 12 ]

241 голосов
/ 21 августа 2010

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

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

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


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

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

Для решения этих проблем была введена кодировка Base64 . Это позволяет вам кодировать байты aribtrary в байты, которые, как известно, безопасны для отправки без повреждения (буквенно-цифровые символы 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 поврежден, поэтому мы можем закодировать эти байты в формате Base64 в виде строки Base64:

SGVsbG8sCndvcmxkIQ==

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

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

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

55 голосов
/ 21 августа 2010

Кодирование двоичных данных в 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 и извлекать данные изображения.

35 голосов
/ 21 августа 2010

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

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

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

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

26 голосов
/ 21 августа 2010

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

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

16 голосов
/ 21 августа 2010

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

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

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

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

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

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

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

MIME-версия: 1.0
Content-Description: "Base64 encode of a.gif"
Content-Type: image / gif;name = "a.gif"
Content-Transfer-Encoding: Base64
Content-Disposition: вложение;filename = "a.gif"

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

12 голосов
/ 21 августа 2010

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

11 голосов
/ 09 сентября 2017

Base64 вместо экранирования специальных символов

Я приведу совсем другой, но реальный пример: я пишу код JavaScript для запуска в браузере.HTML-теги имеют значения идентификаторов, но есть ограничения на то, какие символы допустимы в идентификаторе.

Но я хочу, чтобы мой идентификатор без потерь ссылался на файлы в моей файловой системе.В действительности файлы могут содержать самые разные странные и замечательные символы: восклицательные знаки, акцентированные символы, тильду и даже смайлики!Я не могу сделать это:

<div id="/path/to/my_strangely_named_file!@().jpg">
    <img src="http://myserver.com/path/to/my_strangely_named_file!@().jpg">
    Here's a pic I took in Moscow.
</div>

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

# ERROR
document.getElementById("/path/to/my_strangely_named_file!@().jpg");

Я думаю, что этот код завершится ошибкой при выполнении.

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

document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");

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

Хотелось бы знать о Base64 лет назад.Я бы не стал рвать на себе волосы с помощью 'encodeURIComponent' и str.replace(‘\n’,’\\n’)

SSH передачи текста:

Если вы пытаетесь передавать сложные данные через ssh (например, файл точек)так что вы можете получить свою персонализацию оболочки), удачи вам сделать это без Base 64. Это то, как вы будете делать это с Base 64 (я знаю, что вы можете использовать SCP, но для этого потребуется несколько команд - что усложняет привязку клавиш для sshing всервер):

10 голосов
/ 21 августа 2010

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

6 голосов
/ 21 августа 2010

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

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

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

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

  • Байты 0x0A и 0x0D, используемые для окончаний строк, которые различаются в зависимости от платформы.
  • Другие управляющие символынапример, 0x00 (NULL = терминатор строки C), 0x03 (END OF TEXT), 0x04 (END OF TRANSMISSION) или 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, потому что вам приходится все время конвертировать.

5 голосов
/ 17 апреля 2018

Почему / Как мы используем кодировку Base64?

Base64 - это одна из схем двоичного кодирования с эффективностью 75%. Он используется для того, чтобы типичные двоичные данные (такие как изображения) могли безопасно отправляться по устаревшим «не 8-битным чистым» каналам. В более ранних сетях электронной почты (до начала 1990-х годов) большинство сообщений электронной почты представляли собой простой текст в 7-битном наборе символов US-ASCII. Так много ранних стандартов протокола связи были разработаны для работы над "7-битными" ссылками связи "не 8-битными чистыми". Эффективность схемы - это соотношение между количеством битов на входе и количеством битов на кодированном выходе. Шестнадцатеричное (Base16) также является одной из схем двоичного кодирования с эффективностью 50%.

Шаги кодирования Base64 (упрощенно):

  1. Двоичные данные расположены в виде непрерывных кусочков по 24 бита (3 байта) каждый.
  2. Каждый 24-битный блок сгруппирован в четыре части по 6 бит.
  3. Каждая 6-битная группа преобразуется в соответствующие им значения символов Base64, то есть кодировка Base64 преобразует три октета в четыре закодированных символа. Отношение выходных байтов к входным байтам составляет 4: 3 (33% служебных данных).
  4. Интересно, что одни и те же символы будут кодироваться по-разному в зависимости от их положения в трехоктетной группе, которая кодируется для получения четырех символов.
  5. Получатель должен будет отменить этот процесс, чтобы восстановить исходное сообщение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...