Pull to refresh

SGVsbG8gd29ybGQh или история base64

Reading time 3 min
Views 65K

Краткая предыстория


Вообще, все началось давно. Настолько давно, что вряд ли остались свидетели holy wars тех дней, когда решалось — сколько же бит должно быть в байте.

Это сейчас нам кажется само собой разумеющимся, что 1 байт = 8 бит, что в байте можно закодировать 256 различных значений. Но когда-то было совсем не так. История помнит и семибитные кодировки, и шестибитные, и даже более экзотические системы (например — ЭВМ «Сетунь», которая использовала троичную логику, то есть один троичный бит — трит мог иметь три, а не два значения, для нее было справедливо соотношение 1 трайт = 6 тритам). Но если оставить в стороне всякую экзотику, то мэйнстримом все-таки были кодировки, в которых 6, 7 или 8 бит в байте.

Шестибитная кодировка (например — BCD) позволяла закодировать в одном байте 64 различных значения, что, как казалось, было вполне достаточно для кодирования алфавитно-цифровых символов, а «лишний» седьмой бит расширял кодировку уже до 128 символов.

Однако скоро восьмибитный байт стал общепринятым.

Проблема восьмого бита


Утверждение восьмибитных кодировок как стандарта де-факто принесло много проблем. К этому моменту уже существовала определенная инфраструктура, использующая именно семибитные кодировки, и holy wars разгорелись с новой силой.

До нас они дошли в виде проблем с «обрезанием восьмого бита» в системе электронной почты. Утверждение восьмибитного байта дало 256 различных значений для одного байта, что, в свою очередь позволило уместить в одной кодовой таблице и общепринятые символы (цифры, знаки препинания, латиницу) и символы, скажем кириллицы. Казалось бы — сплошное удобство, текст можно набирать хоть русскими буквами, хоть английскими, а если нужно — и для немецких умлаутов место найдется!

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

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

Для временного решения этой проблемы было предложено несколько вариантов. Одним из них стала кодировка «КОИ-8». Решение, нужно признать, весьма элегантное — в этой кодировке русские буквы располагались по порядку латинских и отличались от них ровно на тот самый старший бит. Таким образом при обрезании этого бита русская «А» превращалась в латинскую «A», «Б» — в «B» и так далее, сообщение просто транслитерировалось и его все-таки можно было прочитать. Правда, и тут не обошлось без скелета в шкафу — сортировка в русском алфавитном порядке в «КОИ» становилась кошмаром…

А что было делать другим языкам, народам и кодировкам? А бинарные данные? Все равно кодировки с транслитерацией не решали фундаментальную проблему — потерю восьмого бита, потерю части информации. Так родилась кодировка (а точнее — алгоритм) Base64.

Алгоритм Base64


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

В основе алгоритма лежит сведение трех восьмерок битов (24) к четырем шестеркам (тоже 24) и представление этих шестерок в виде символов ASCII. Таким образом получается обратимое шифрование, единственным недостатком которого будет увеличивающийся при кодировании размер — в соотношении 4:3.

Пример:
Возьмем текст русский текст «АБВГД». В двоичной форме в кодировке Windows-1251 мы получим 5 байтов:
11000000
11000001
11000010

11000011
11000100
(00000000) — лишний нулевой байт нужен, чтобы общее число бит делилось на 6

Разделим эти биты на группы по 6:
110000
001100
000111
000010

110000
111100
010000
000000

Берем массив символов «ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/» и получившиеся числа переводим в эти символы, используя их, как индексы массива, получаем «wMHCw8Q». Остается только добавить в конце один символ "=", как указание на один лишний нулевой байт, который мы добавляли на первом шаге и получить окончательный результат:

«АБВГД»: base64 = «wMHCw8Q=»

Обратное преобразование не менее легко, попробуйте, например, расшифровать то, что вынесено в заголовок этой статьи.

Применение


Алгоритм base64 и по сей день применяется там, где нет возможности гарантировать бережного обращения с вашей информацией — например при кодировании вложений электронной почты. В PGP алгоритм base64 используется для кодирования бинарных данных.

Можно представить себе и другие применения base64 — например при сохранении в базу данных, если заранее неизвестно окружение (ох уж эти magic_qoutes в PHP!) и нет необходимости в индексации и поиске по тексту, можно воспользоваться base64.

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

Ну и наконец Data URI

Ссылки


ru.wikipedia.org/wiki/Base64
base64.ru
Tags:
Hubs:
+57
Comments 36
Comments Comments 36

Articles