В вычислительной технике: кодирование - это процесс преобразования информации или инструкции в определенную форму.
Зачем нам вообще нужно кодировать информацию?
Допустим, вам нужно перенести данные из приложения A в B, а затем в C.
Приложение A - использует схему кодирования X.
Приложение B - использует схему кодирования Q, которая является подмножеством X.
Приложение C - использует ту же схему кодирования, что и A.
Вы заметили здесь проблему?
Отправка данных в кодировке X из приложения A в B вызовет много проблем, поскольку приложение B не сможет чтобы правильно интерпретировать некоторые данные, если не все отправлены из приложения A.
Давайте будем более конкретными.
Приложение A - использует схему кодировки UTF-8.
Приложение B - использует схему кодирования ASCII и не поддерживает никакую другую.
Приложение C - использует ту же схему кодирования, что и приложение A.
Лучшим решением было бы отправить данные из приложения A в C, но если вам обязательно нужно сначала отправить данные в приложение B, тогда мы должны закодировать данные в том, что A и B могут понять, а затем декодировать их обратно в то, что только A и C может понять, когда он дойдет до C.
Во-первых, мы должны понять, как работает кодировка UTF-8 и ASCII:
Для UTF-8:
2 164 864 «символа» потенциально могут быть закодированы.
Это число 2⁷ + 2¹¹ + 2¹⁶ + 2²¹, что зависит от способа работы кодировки:
- 1-байтовые символы имеют 7 бит для кодирования
0xxxxxxx
- (ASCII) - 2-байтовые символы имеют 11 бит для кодирования
110xxxxx 10xxxxxx
- 3-байтовые символы имеют 16 бит для кодирования
1110xxxx 10xxxxxx 10xxxxxx
- 4-байтовые символы имеют 21 бит для кодирования
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Как мы видим, ASCII (128) - это всего лишь часть символов UTF-8 (2 164 864).
Как работает кодировщик base64?
Кодировщик base64 использует только 64 символа (A-Z, a-z, 0–9, +, /) из набора символов ASCII.
Стоит отметить, что кодировщику Base64 требуется всего 6 бит для представления всех символов в таблице. В символах ASCII используется 8 бит, следовательно, наименьшее число, которое может быть успешно закодировано без манипуляции с битами, будет 24 бита (наименьшее число 6 и 8 будет делиться без остатка)
Мой алгоритм кодирования данных в формате base64:
- Получите байтовое представление данных.
- Извлеките первые шесть битов из байтовой строки, преобразуйте их в десятичное и найдите таблицу набора символов Base64, чтобы получить соответствующее значение, добавьте это значение в закодированную строку.
- Повторяйте этот процесс, пока не дойдете до последнего набора битов, дополните последний набор битов нулем вправо до шести битов, если их не больше шести, и проверьте соответствующее значение в таблице.
Этого вполне достаточно для кодирования наших данных в формате base64, но недостаточно для декодирования, когда они попадают в приложение C, base64 выходит за рамки этого руководства, но вот дополнительные правила, необходимые для простого декодирования:
Вычислите длину байтовой строки и разделите ее на 24:
- если остаток равен 18, мы добавляем «=» к закодированной строке, это означает, что закодированная строка короче 6 бит.
- если остаток равен 12, мы добавляем «==» к закодированной строке, это означает, что закодированная строка короче 12 бит.
- если остаток равен 6, мы ничего не добавляем к закодированной строке, но это указывает на то, что закодированная строка короче на 18 бит
Я реализовал алгоритм с php ниже:
$base64StringMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; $base64StringMapArray = str_split($base64StringMap); $inputString = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."; $inputStringArray = str_split($inputString); $inputStringLength = count($inputStringArray); $inputStringBits = ""; for ($i = 0; $i < $inputStringLength; $i++) { $stringInBits = decbin(ord($inputStringArray[$i])); $inputStringBits .= str_pad($stringInBits,8,"0",STR_PAD_LEFT); } $offset = 0; $length = 6; $noOfIterations = ceil(strlen($inputStringBits)/$length); $padZeros = strlen($inputStringBits) + (6 - strlen($inputStringBits)%$length); $base64EncodedString = ""; if ($padZeros > 0) { $inputStringBits = str_pad($inputStringBits,$padZeros,"0",STR_PAD_RIGHT); } for ($i = 0; $i < $noOfIterations; $i++) { $base64EncodedString .= $base64StringMapArray[bindec(substr($inputStringBits, $offset, $length))]; $offset += $length; } $inputStringLastBitsBlockLength = strlen($inputStringBits) % 24; if ($inputStringLastBitsBlockLength == 18) { $base64EncodedString .= "="; } else if ($inputStringLastBitsBlockLength == 12) { $base64EncodedString .= "=="; } echo $base64EncodedString;
Обратите внимание, что существуют более эффективные алгоритмы и библиотеки кодирования base64, цель этой статьи - не реализация, а то, как работает кодирование base64.
Спасибо за прочтение. !!!