Для чего используется кодировка base 64?

782

Я слышал, как люди говорили о «кодировании base 64» здесь и там. Для чего его используют?

MrDatabase
источник
1
Из руководства для base64_encode () : «Эта кодировка разработана, чтобы заставить двоичные данные выживать при транспортировке через транспортные уровни, которые не являются 8-битными, например, почтовые тела».
still_dreaming_1

Ответы:

941

Когда у вас есть некоторые двоичные данные, которые вы хотите отправить по сети, вы обычно не делаете это, просто передавая биты и байты по проводам в необработанном формате. Почему? потому что некоторые медиа сделаны для потокового текста. Вы никогда не знаете - некоторые протоколы могут интерпретировать ваши двоичные данные как управляющие символы (например, модем), или ваши двоичные данные могут быть испорчены, потому что базовый протокол может подумать, что вы ввели специальную комбинацию символов (например, как FTP переводит строку окончания).

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

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

Дейв Маркл
источник
104
(Теоретически вы могли бы сделать кодирование base-80 или что-то подобное, но это было бы значительно сложнее. Полномочия двух являются естественными основами для двоичного кода.)
Джон Скит
13
@yokees: нет гарантии, это просто персонажи, которые почти всегда в безопасности. Вот почему существует несколько форм Base-64 ( en.wikipedia.org/wiki/Base-64 ).
8
Означает ли это, что при передаче данных любого типа сети должна использоваться какая-то кодировка?
Тэннер Саммерс
6
Но почему метод base64 используется для кодирования строковых данных? например, в javascript atob function. Имеет ли смысл сервер для кодирования файла json в формат base64? Специальные символы могли бы быть вариантом использования, но почему бы не utf8 в этом случае, они эквивалентны? Любой дальнейший ресурс относительно этого был бы очень признателен, спасибо.
partizanos
4
Список хотя бы некоторых протоколов, которые потерпят неудачу, было бы неплохо иметь, если кто-то знает.
Тадей
202

Это в основном способ кодирования произвольных двоичных данных в тексте ASCII. Требуется 4 символа на 3 байта данных, плюс, возможно, небольшой отступ в конце.

По сути, каждые 6 бит ввода кодируются в 64-символьном алфавите. «Стандартный» алфавит использует AZ, az, 0-9 и + и /, с = в качестве символа заполнения. Есть URL-безопасные варианты.

Википедия - достаточно хороший источник дополнительной информации.

Джон Скит
источник
В языке, подобном php, будут получены двоичные данные. Мы почти всегда работаем со строковыми данными, которые являются текстовыми.
Чолти Пол Ттиопик
3
@CholthiPaulTtiopic: результаты шифрования или сжатия, или звука / изображения / видео.
Джон Скит
1
@CholthiPaulTtiopic: Боюсь, я понятия не имею, что вы подразумеваете под «как насчет хранилища», но на данный момент я думаю, что мы несколько не в теме.
Джон Скит
2
@CholthiPaulTtiopic: я бы сильно избегал думать в терминах «бинарного файла». Двоичные данные должны рассматриваться как двоичные данные, а не как текст. Я видел буквально сотни - возможно, тысячи - вопросов по SO, которые в основном сводятся к людям, которые недостаточно заботятся об этом различии.
Джон Скит
1
@ still_dreaming_1 PHP вызывает их binary strings. (источник) php.net/manual/en/function.pack.php
Cholthi Paul Ttiopic
123

Кодирование Base-64 - это способ взять двоичные данные и преобразовать их в текст, чтобы их было легче передавать в таких вещах, как электронная почта и данные HTML-формы.

http://en.wikipedia.org/wiki/Base64

Брэд Уилсон
источник
116

Это текстовая кодировка двоичных данных, в которой результирующий текст содержит только буквы, цифры и символы «+», «/» и «=». Это удобный способ хранения / передачи двоичных данных через носитель, который специально используется для текстовых данных.

Но почему Base-64? Две альтернативы для преобразования двоичных данных в текст, которые сразу приходят на ум:

  1. Десятичное число: сохранить десятичное значение каждого байта в виде трех чисел: 045 112 101 037 и т. Д., Где каждый байт представлен 3 байтами. Данные раздуты в три раза.
  2. Шестнадцатеричный: сохранить байты в виде шестнадцатеричных пар: AC 47 0D 1A и т. Д., Где каждый байт представлен 2 байтами. Данные раздуты в два раза.

Base-64 отображает 3 байта (8 x 3 = 24 бита) в 4 символа, которые охватывают 6 бит (6 x 4 = 24 бита). Результат выглядит примерно так: «TWFuIGlzIGRpc3Rpb ...». Таким образом, вздутие живота составляет всего лишь 4/3 = 1,3333333 раза от оригинала.

Атес Горал
источник
10
Правильно ли я понимаю, что 64 - лучший выбор, так как это наивысшая степень двух, которая может быть преобразована в печатный символ ASCII (их 95)?
Вохо
Если в обоих случаях они равны 24 битам, то не вздутие лифта 1: 1? Или когда вы говорите 4 символа, которые охватывают 6 битов, вы имеете в виду, что на самом деле 8 символов на символ, но первые два дополняются нулями?
Дэвид Клемпфнер
1
@Backwards_Dave Каждые 6 бит выражаются в 8 битах. Таким образом, вздутие живота составляет 8: 6 или 4: 3.
Атес Горал
82

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

Хэш:

Хэши - это односторонние функции, которые преобразуют блок байтов в другой блок байтов фиксированного размера, например 128 или 256 бит (SHA / MD5). Преобразование полученных байтов в Base64 значительно упрощает отображение хеша, особенно когда вы сравниваете контрольную сумму на целостность. Хеши так часто встречаются в Base64, что многие люди ошибочно принимают сам Base64 как хэш.

Криптография:

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

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

Сертификаты

Сертификаты x509 в формате PEM кодируются в формате base64. http://how2ssl.com/articles/working_with_pem_files/

Деспертар
источник
4
На самом деле во многих случаях проще обрабатывать байты как байты. Даже в базе данных, и особенно в файле (если используются записи фиксированной длины или байты являются единственным содержимым). Base64 обычно используется, когда эти байты предназначены для передачи куда-либо, особенно по каналу, который может обрезать биты или интерпретировать некоторые байты как управляющие коды.
Чао
Я никогда не видел хэш, записанный в виде 8-разрядных целых чисел без знака, 0,1255,36 ... и отображение его с помощью UTF-8 или любой другой кодировки не имело бы смысла, как иначе вы бы отобразили его, кроме как с base64? Ключи шифрования и зашифрованные данные часто хранятся в файлах конфигурации и XML, где вы не можете хранить необработанные байты. Я согласен, если вы можете хранить его как необработанные байты, то непременно, но base64 для тех ситуаций, когда вы не можете. Существует много применений base64 помимо передачи. Это просто два распространенных сценария, в которых вы увидите это.
Despertar
1
Вы бы отобразили хеш как шестнадцатеричный, а не десятичный. Для хэшей это на самом деле гораздо чаще, чем base64.
Чао
@cHao Да, это также распространено. Шестнадцатеричные цифры могут представлять любые двоичные данные, но преимущество базы 64 состоит в том, что она занимает гораздо меньше места, поскольку использует больше символов.
Despertar
45

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

Проблема с двоичными данными состоит в том, что они содержат нулевые символы, которые в некоторых языках, таких как C, C ++, представляют конец символьной строки, поэтому отправка двоичных данных в необработанном виде, содержащем NULL-байты, не дает файлу полностью считываться и приводит к поврежденным данным.

Например :

В C и C ++ этот «нулевой» символ показывает конец строки. Так что "Привет" хранится так:

ПРИВЕТ

72 69 76 76 79 00

00 говорит "остановись здесь".

Теперь давайте рассмотрим, как работает кодирование BASE64.

Обратите внимание: длина строки должна быть кратна 3.

Пример 1:

Строка для кодирования: «туз», длина = 3

1) Конвертировать каждый символ в десятичную.

а = 97, с = 99, е = 101

введите описание изображения здесь

2) Измените каждое десятичное на 8-битное двоичное представление.

97 = 01100001, 99 = 01100011, 101 = 01100101

Комбинированный: 01100001 01100011 01100101

3) Отдельно в группе 6 бит.

011000 010110 001101 100101

4) Рассчитать двоичное в десятичное

011000 = 24, 010110 = 22, 001101 = 13, 100101 = 37

5) Преобразование десятичных символов в base64 с использованием диаграммы base64.

24 = Y, 22 = W, 13 = N, 37 = l

«Туз» => «YWNl»

введите описание изображения здесь

Пример 2:

Строка для кодирования: «abcd» Length = 4, она не кратна 3. Поэтому, чтобы сделать длину строки кратной 3, мы должны добавить 2-битовое заполнение, чтобы сделать length = 6. Бит заполнения представлен знаком «=».

Следует отметить: один бит дополнения равен двум нулям 00, поэтому два бита дополнения равны четырем нулям 0000.

Итак, давайте начнем процесс: -

1) Конвертировать каждый символ в десятичную.

а = 97, б = 98, с = 99, д = 100

2) Измените каждое десятичное на 8-битное двоичное представление.

97 = 01100001, 98 = 01100010, 99 = 01100011, 100 = 01100100

3) Отдельно в группе 6 бит.

011000, 010110, 001001, 100011, 011001, 00

поэтому последний 6-бит не является полным, поэтому мы вставляем два дополнительных бита, равных четырем нулям «0000».

011000, 010110, 001001, 100011, 011001, 000000 ==

Теперь оно равное. Два знака равенства в конце показывают, что были добавлены 4 нуля (помогает при декодировании).

4) Рассчитать двоичные числа в десятичные.

011000 = 24, 010110 = 22, 001001 = 9, 100011 = 35, 011001 = 25, 000000 = 0 ==

5) Преобразование десятичных символов в base64 с использованием диаграммы base64.

24 = Y, 22 = W, 9 = j, 35 = j, 25 = Z, 0 = A ==

«Abcd» => «YWJjZA ==»

Раджеш Праджапати
источник
5
это действительно отличное объяснение
maheshmnj
28

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

Следовательно, 0x01 будет передано как 0x81; 0x02 будет 0x82; 0x03 останется 0x03 и т. Д.

Для дальнейшего развития этой системы, когда был определен набор символов ASCII, только 00-7F были назначены символы. (До сих пор все символы в диапазоне 80-FF нестандартны)

Многие современные маршрутизаторы устанавливают проверку четности и перевод байтов в аппаратные средства, заставляя подключенные к ним компьютеры строго обрабатывать 7-битные данные. Это заставляет вложения электронной почты (и все другие данные, поэтому протоколы HTTP и SMTP основаны на тексте) для преобразования в текстовый формат.

Немногие из роутеров выжили в 90-х годах. Я сильно сомневаюсь, что любой из них используется сегодня.

Джеймс Керран
источник
2
Это отличная тема для обсуждения и интересный урок истории, спасибо.
Дэн Бешард
26

С http://en.wikipedia.org/wiki/Base64

Термин Base64 относится к конкретной кодировке передачи контента MIME. Он также используется в качестве общего термина для любой подобной схемы кодирования, которая кодирует двоичные данные, обрабатывая их численно и переводя в представление base 64. Конкретный выбор базы обусловлен историей кодировки набора символов: можно выбрать набор из 64 символов, который является частью подмножества, общего для большинства кодировок, а также для печати. Эта комбинация оставляет данные, которые вряд ли будут изменены при передаче через системы, такие как электронная почта, которые традиционно не были 8-битными чистыми.

Base64 может использоваться во множестве контекстов:

  • Evolution и Thunderbird используют Base64 для маскировки паролей электронной почты [1]
  • Base64 может использоваться для передачи и хранения текста, который в противном случае мог бы вызвать коллизию
  • Base64 часто используется в качестве быстрого, но небезопасного ярлыка для скрытия секретов без дополнительных затрат на управление криптографическим ключом.

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

  • Base64 используется для кодирования символьных строк в файлах LDIF
  • Base64 иногда используется для встраивания двоичных данных в файл XML, используя синтаксис, подобный ...... например, Firefox's bookmarks.html.
  • Base64 также используется при обмене данными с правительственными печатающими устройствами Fiscal Signature (обычно через последовательные или параллельные порты), чтобы минимизировать задержку при передаче символов квитанции для подписи.
  • Base64 используется для кодирования двоичных файлов, таких как изображения, в скриптах, чтобы избежать зависимости от внешних файлов.
  • Может использоваться для встраивания необработанных данных изображения в свойство CSS, например background-image.
кроличий садок
источник
11

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

Конрад Рудольф
источник
9

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

У меня возникли проблемы, когда я обнаружил, что MySQL utf8 не поддерживает 4-байтовые символы Unicode, поскольку он использует 3-байтовую версию utf8. Так что же я сделал для поддержки полного 4-байтового юникода поверх utf8 MySQL? Хорошо, base64 кодирует строки при сохранении в базе данных и base64 декодирует при извлечении.

Поскольку кодирование и декодирование base64 выполняется очень быстро, все вышеперечисленное работает отлично.

У вас есть следующие моменты, чтобы принять к сведению:

  • Кодировка Base64 использует на 33% больше памяти

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

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

Василий Муса
источник
6
«Вы можете продать это как функцию, в которой строки базы данных используют базовую форму шифрования». Мне нравится ваш стиль: D
Ercan
9
«Вы можете продать это как функцию, в которой строки базы данных используют базовую форму шифрования», что ужасно сказать: D
Alex
1
Базовая форма шифрования против тех, у кого нет алгоритма декодирования base64 rofl: D
Eladian
1
@ Алекс Нисколько не "ужасная вещь, чтобы сказать". Чувствительные данные второй степени допустимы для кодирования base64, чтобы администраторы БД не могли их прочитать. Не всегда необходимо иметь самый высокий уровень шифрования для каждого фрагмента данных. Например, если вы хотите скрыть «комментарии» от администратора БД, тогда base64 подходит для этой работы. Gratcias!
Василий Муса
1
Стоит отметить, что MySQL теперь поддерживает все Unicode, хотя в целях обратной совместимости их utf8тип по-прежнему составляет только три байта; если хочешь настоящего, используй utf8mb4. Хороший взлом, но больше не нужен.
TRiG
7

Он используется для преобразования произвольных двоичных данных в текст ASCII.

Например, вложения электронной почты отправляются таким образом.

Can Berk Güder
источник
7

Я использую его в практическом смысле, когда мы передаем большие двоичные объекты (изображения) через веб-сервисы. Поэтому, когда я тестирую веб-сервис C # с использованием скрипта Python, бинарный объект может быть воссоздан с небольшим количеством волшебства.

[В питоне]

import base64
imageAsBytes = base64.b64decode( dataFromWS )
Эндрю Кокс
источник
1
Данные перемещаются быстрее?
FelipeM
1
@FelipeM медленнее, а не быстрее. Base64 имеет 33% накладных расходов (по цене безопасности.)
Юрай
6

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

Пример может быть следующим: у вас есть веб-сервис, который принимает только символы ASCII. Вы хотите сохранить, а затем перенести данные пользователя в другое место (API), но получатель хочет получить нетронутые данные. Base64 для этого. , , Единственным недостатком является то, что для кодирования base64 потребуется примерно на 33% больше места, чем для обычных строк.

Другой пример :: uenc = URL кодированные = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.querytip.com/asics-men-s-gel-kayano-xii.html .

Как вы можете видеть, мы не можем поместить символ «/» в URL, если мы хотим отправить последний посещенный URL в качестве параметра, потому что мы нарушили бы правило атрибута / значения для «MOD rewrite» - параметр GET.

Полный пример может быть следующим: « http://loc.querytip.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product / 93 / »

jmr333
источник
4

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

Эрик Таттлман
источник
3

Чтобы немного рассказать о том, что говорит Брэд: многие транспортные механизмы для электронной почты и Usenet, а также другие способы перемещения данных не являются «8-битными чистыми», это означает, что символы вне стандартного набора символов ascii могут быть искажены при передаче - например, 0x0D может рассматриваться как возврат каретки и превращается в возврат каретки и перевод строки. Base 64 отображает все двоичные символы в несколько стандартных букв и цифр ascii и знаков препинания, поэтому они не будут искажены таким образом.

Пол Томблин
источник
2

Base64

Base64 - это общий термин для ряда аналогичных схем кодирования, которые кодируют двоичные данные, обрабатывая их численно и переводя в представление base 64. Термин Base64 происходит от конкретной кодировки передачи контента MIME.

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

Mugil K
источник
0

Base64 может использоваться для многих целей.

Основной причиной является преобразование двоичных данных во что-то сносное.

Иногда я использую его для передачи данных JSON с одного сайта на другой, хранения информации о пользователях в файлах cookie.

Примечание: вы «можете» использовать его для шифрования - я не понимаю, почему люди говорят, что вы не можете, и что это не шифрование, хотя его легко взломать и осудить. Шифрование означает не что иное, как преобразование одной строки данных в другую строку данных, которая может быть либо расшифрована позднее, либо нет, и именно это делает base64.

Джоди Фицпатрик
источник
2
Вы интерпретируя определение «шифрования» далеко слишком буквально. Слово превратилось в нечто более конкретное, чем его происхождение.
Дэн Бешард
0

Одна шестнадцатеричная цифра состоит из одного куска (4 бита). Два полубайта составляют 8 битов, которые также называются 1 байтом.

MD5 генерирует 128-битный выход, который представлен с использованием последовательности из 32 шестнадцатеричных цифр, которые в свою очередь составляют 32 * 4 = 128 бит. 128 бит составляют 16 байтов (поскольку 1 байт равен 8 битам).

Каждый символ Base64 кодирует 6 битов (кроме последнего символа без пэда, который может кодировать 2, 4 или 6 битов, и финальных символов пэда, если таковые имеются). Следовательно, для каждой кодировки Base64 для 128-битного хэша требуется не менее /128 / 6⌉ = 22 символа, плюс пробел, если он есть.

Используя base64, мы можем создать закодированный вывод нужной длины (6, 8 или 10). Если мы решим выбрать вывод длиной 8 символов, он занимает всего 8 байтов, тогда как он занимал 16 байтов для 128-битного вывода хеша.

Таким образом, в дополнение к безопасности, кодировка base64 также используется для уменьшения занимаемого пространства.

Jainabhi
источник