Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

ZBase32, Base32 и Base64 алгорифмы кодирования

Anna | 18.06.2014 | нет комментариев
Многие применяют Base64 кодирование, реже Base32 и еще реже ZBase32 (вы знаете о таком?), но не все понимают их алгорифмы. В статье я описываю превосходства, недочеты данных кодировок, а также рассказываю о их реализации.

Не так давным-давно у меня появилась надобность применять кодированные данные в адресе http-ссылки. Как вестимо, эталон http подразумевает регистронезависимые url-адреса и всякий прокси-сервер либо браузер мог испортить данные в случае применения регистрочувствительного кодирования.Рассматривая указанные требования в качестве алгорифма было выбрано ZBase32-кодирование.
Как оказалось, стандартной реализации в .net нет (в различие от base64), следственно пришлось писать самому. К своему изумлению, я столкнулся с сложностями при поиске ясного объяснения Base32 и ZBase32. Были обнаружены какие-то готовые решения, но я не мог, не разобравшись в алгорифме использовать их, а читать магию крупных формул, битовых сдвигов было трудно без словесного изложения. Сейчас, когда для меня все позади, я хотел бы поделиться с вами небольшим познанием элементарного кодирования. Статья носит академический нрав.

Плюсы и минусы

Base64

Разрешает кодировать информацию, представленную комплектом байтов, применяя каждого 64 символа: A-Z, a-z, 0-9, /, . В конце кодированной последовательности может содержаться несколько спецсимволов (обыкновенно “=”).

Превосходства:

  • Разрешает представить последовательность всяких байтов в печатных символах.
  • В сопоставлении с другими Base-кодировками дает итог, тот, что составляет только 130% от длины начальных данных.

Недочеты:

  • Регистрозависимая кодировка.
Base32

Использует только 32 символа: A-Z (либо a-z), 2-7. Может содержать в конце кодированной последовательности несколько спецсимволов (по аналогии с base64).

Превосходства:

  • Последовательность всяких байтов переводит в печатные символы.
  • Регистронезависимая кодировка.
  • Не применяются цифры, слишком схожие на буквы (скажем, 0 схож на О, 1 на l).

Недочеты:

  • Кодированные данные составляют 160% от начальных.
ZBase32

Кодировка аналогична Base32, но имеет следующие различия.

  • Человеко-ориентированный алфавит из 32 символов. Особенно проработанная таблица символов для упрощения написания, произношения и запоминания кодированной информации. Авторы переставили особенно комфортные для человека символы на позиции, которые применяются Почаще каждого. Как они это сделали я не знаю. Алфавит приводится ниже.
  • Нет особых символов в конце итога кодирования.

Подробнее про всякую из кодировок дозволено почитать в Википедии тут и тут, а теперь я хотел бы остановиться непринужденно на реализации ZBase32.

Изложение алгорифма ZBase32 кодирования

Дозволю себе при изложении алгорифма показывать выкладки на C# для большего понимания.

Выходит, имеем 32-х символьный алфавит дальнейшего оглавления:

static string EncodingTable = "ybndrfg8ejkmcpqxot1uwisza345h769";

На входе массив байтов (безусловно, по 8 бит всякий), тот, что хотелось бы перевести в символы из алфавита.

public static string Encode(byte[] data)
{

Алфавит представляет собой строку из 32-х элементов, а это обозначает, что всякий из его символов кодируется числом от 0 до 31 (индексы символов в строке). Как вестимо, всякое число от 0 до 31 в бинарной системе счисления дозволено записать, применяя 5 битов байта. Из этого следует, что если представить начальный комплект байтов как цельный массив битов и разбить его на ломтики по 5 битов (см. рисунок ниже), то мы получим комплект координат символов из алфавита. Вот, собственно, и все.

Алгорифмы Base32 и Base64 аналогичны ZBase32, только различные алфавиты (по составу в случае с Base32, по составу и размеру в случае Base64) и размеру “отщипываемых” ломтиков бит (6 бит для Base64).

Выходит, я предлагаю перед тем, как начать разбиение начальных данных на ломтики по 5 бит, подготовить место куда будет записываться итог. Дабы не задумываться об индексах в статических массивах, давайте применять StringBuilder.

var encodedResult = new StringBuilder((int)Math.Ceiling(data.Length * 8.0 / 5.0));

При инициализации сразу задаем размер результирующей строки (Дабы не тратить время на растяжение в процессе работы алгорифма).

Сейчас осталось пробежать по начальному массиву байтов и поделить его на 5-и битовые ломтики. Для комфорта я предлагаю трудиться с группой по 5 байтов, так как это 40 бит — число, кратное длине “кусочков”. Но не забываем, что начальные данные никто для нас не подгонял, следственно рассматриваем вероятность дефицита.

for (var i = 0; i < data.Length; i  = 5)
{
     var byteCount = Math.Min(5, data.Length - i);

Так как мы трудимся с группой из 5 байтов, нам необходим буфер, где будет формироваться сплошной комплект битов (каждого 40 бит). Заведем переменную типа ulong (64 бита в нашем распоряжении) и разместим туда нынешнюю партию байтов.

ulong buffer = 0;
for (var j = 0; j < byteCount;   j)
{
      buffer = (buffer << 8) | data[i   j];
}

И заключительный этап — это “отщипывание” из того, что получилось, ломтиков по 5 бит и образование итога.

var bitCount = byteCount * 8;
while (bitCount > 0)
{                    
      var index = bitCount >= 5
                          ? (int)(buffer >> (bitCount - 5)) & 0x1f
                           : (int)(buffer & (ulong)(0x1f >> (5 - bitCount))) << (5 - bitCount);

      encodedResult.Append(EncodingTable[index]);
      bitCount -= 5;
}

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

Процесс декодирования происходит подобно процессу кодирования, только в обратном направлении.

Вы можете посмотреть полную реализацию ZBase32Encoder.

Завершение

И, безусловно, в завершение хочется сказать следующее.

4nq7bcgosuemmwcq4gy7ddbcrdeadwcn4napdysttuea6egosmembwfhrdemdwcm4n77bcby4n97bxsozzea9wcn4n67bcby4nhnbwf94n9pbq6oszemxwf74nanhegow8em9wfo4gy7bqgos8emhegos9emyegosmem5wfa4n6pbcgozzemtwfirr

 

 Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB