4883

Кодирование данных. Алгоритм Base64

Лекция

Информатика, кибернетика и программирование

Кодирование данных. Алгоритм Base64. Под кодом понимают определенную систему условных обозначений или сигналов, а процесс кодирования – это переход от одной формы представления информации к другой. При этом целью кодирования, как правило,...

Русский

2012-11-28

41.5 KB

41 чел.

Кодирование данных. Алгоритм Base64.

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

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

 Поскольку общее количество стандартных печатных знаков (26 строчных букв + 26 прописных + 10 цифр + небольшое количество знаков пунктуации и спец. символов) гораздо меньше диапазона значений произвольного байта данных (0~255), в основе алгоритма Base64 лежит преобразование 8-битной последовательности в последовательность элементов меньшей разрядности. С практической точки зрения наиболее удобно выбрать разрядность элементов выходной последовательности так, чтобы использовалось максимально возможное количество допустимых печатных знаков. Дополнив множество букв и цифр (всего 62 элемента) двумя произвольными знаками пунктуации (обычно ‘+’ и ‘/’), получим удобный код, каждому символу которого можно однозначно поставить в соответствие 6-битное двоичное число (26=64).

В итоге, получаем эффективный алгоритм кодирования: входная последовательность 8-битных данных разбивается на блоки по 3 байта (24 бит), каждый блок разбивается на 4 6-битных элемента (24/6 =4). Далее каждому 6-битному элементу ставится в соответствие один из печатных кодовых символов. В итоге получается последовательность печатных символов, допустимая для передачи по текстовому каналу. При нехватке входных данных для формирования 3-байтного блока, поступают следующим образом: при недостатке одного байта, выходной блок дополняют специальным символом, не входящим в основной кодовый алфавит (обычно ‘=’), при нехватке двух байтов – двумя такими символами.

При раскодировании выполняется обратная процедура – кодовая последовательность «нарезается» на блоки по 4 символа, далее каждому из них ставится в соответствие 6-битное значение и полученная 24-битная строка «нарезается» на блоки по 8 бит.

// Таблица символов кодировки Base64

char B64TABLE[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

const int UNKNOWN_SYMBOL = 100; // При обнаружении недопустимого символа

// Функция кодирует 3 входных байта в 4 выходных

void B64Encode(unsigned char in[3], int len, unsigned char out[4])

{

out[0] = B64TABLE[in[0] >> 2];

out[1] = B64TABLE[((in[0] & 0x03) << 4) | (in[1] >> 4)];

out[2] = B64TABLE[((in[1] & 0x0F) << 2) | (in[2] >> 6)];

out[3] = B64TABLE[in[2] & 0x3F];

 // Если на вход поступило меньше 3х "достоверных" байтов,

 // дополняем выходную последовательность спец. символами '='

 if (len <= 2)

 out[3] = '=';

 if (len == 1)

 out[2] = '=';

}

// Получить индекс символа в таблице B64TABLE

unsigned int getB64Index(unsigned char c)

{

 for (int i=0; i<64; i++)

 if (c == B64TABLE[i])

  return i;

 

 return UNKNOWN_SYMBOL; // Если символ в таблице не найден

}

// Обратное преобразование - 4 входных байта, закодированных

// в Base64, раскодируем в 3 исходных байта, и возвращаем

// количество "достоверных" раскодированных символов

int B64Decode(unsigned char in[4], unsigned char out[3])

{

 for ( int i = 0; i < 4; i++ )

 in[i] = getB64Index( in[i] );

out[0] = ( in[0] << 2 ) | ( ( in[1] & 0x30 ) >> 4 );

out[1] = ( in[1] << 4 ) | ( ( in[2] & 0x3C ) >> 2 );

out[2] = ( in[2] << 6 ) | in[3];

 int len = 3;

 if ( in[2] == UNKNOWN_SYMBOL ) //Символ не найден в таблице ('=')

 len--;

 if ( in[3] == UNKNOWN_SYMBOL )

 len--;

 return len;

}

void main()

{

 char test[] = "Some textx";

 char encoded[100];  // Сюда поместим закодированную последовательность

 

 std::cout << "Original string: "<< test << std::endl;

   // Кодирование

 int j = 0;

 for ( int i = 0; i < strlen( test ); )

 {

 int len = 1;

 unsigned char in[3]; // Временная последовательность для кодирования (буфер)

 

 // Копируем 3 очередных символа из исходной строки в буфер

 in[0] = test[i++];

 if (i<strlen(test))

 {

  in[1] = test[i++];

  len++;

 }

 if (i<strlen(test))

 {

  in[2] = test[i++];

  len++;

 }

 

 unsigned char out[4]; // Буфер для закодированных байтов

 B64Encode(in, len, out);

 // Копируем закодированные байты в результирующую строку

 encoded[j++] = out[0];

 encoded[j++] = out[1];

 encoded[j++] = out[2];

 encoded[j++] = out[3];

 }

 encoded[j] = '\0'; // Добавляем "конец строки" (для вывода на экран)

   // Декодирование

 char decoded[100]; // Сюда поместим раскодированную последовательность

 

 j=0;

 for ( int i = 0; i < strlen( encoded ); )

{

 unsigned char in[4];

 for ( int k = 0; k < 4; k++ )

  in[k] = encoded[ i++ ];

 

 unsigned char out[3];

 int len = B64Decode(in, out);

 for ( int k = 0; k < len; k++ )

  decoded[ j++ ] = out[k];

}

decoded[j] = '\0';

std::cout << "Encoded string: " << encoded << std::endl;

std::cout << "Decoded string: " << decoded << std::endl;

system("pause");

}


 

А также другие работы, которые могут Вас заинтересовать

8402. Китай в ХХ веке 55 KB
  Китай в ХХ веке. Версальский мирный договор 1919г., санкционировавший право Японии на германские владения в Шаньдуне, вызвал волну возмущения в Китае, надеявшимся стать союзником для держав Антанты в 1-й мировой войне. 4 мая 1919г....
8403. Периодизация истории и культуры Древнего Китая 196.5 KB
  Периодизация истории и культуры Древнего Китая Древнейший период - V - III тыс. до н.э. Период Шань-Инь - сер. II тыс. до н.э. (XVI - XI вв. до н.э.), I китайское государство Периоды Чжоу и Чжаньго XI...
8404. Современный Китай: тенденции развития экономики и политики. 119.5 KB
  Современный Китай: тенденции развития экономики и политики. Борьба за реформы и перестановки в КПК. Основные аспекты политической и экономической безопасности КНР. Китай, несмотря на его гигантские успехи в развитии экономики, - остается...
8405. Китайская система менеджмента 1 MB
  Китайская система менеджмента Общая информация о Китае. До недавних пор американские компании переводили свои производственные мощности в Китай и нанимали китайцев для выполнения низкооплачиваемой работы. Теперь ситуация начинает меняться. Китайская...
8406. Древний Китай 64.5 KB
  Древний Китай История Древнего Китая делится на четыре периода, связанных с проявлением определенной династии: 1) Шан (Инь) - XVIII-XII вв. до н.э. 2) Чжоу - 12 в. до н.э. - 221 г. до н.э. 3) Цинь - 221 г. до н.э. - 207 г. до н.э. 4) Хань - 206 г...
8407. Реклама и ценностные ориентиры в обществе 206.38 KB
  Объектом данной курсовой работы является PR-деятельность страховой компании Альфастрахование. Данная компания была выбрана в качестве объекта исследования, так как позиционирует себя как одна из лучших страховых компаний в России и имеет богатую историю, а значит и опыт, в сфере PR-стратегий.
8408. Право средневекового Китая 63.5 KB
  Право средневекового Китая. От этого времени до нас дошли два важных правовых памятника: Уголовное установление Тан (Тан Люй Шу И), составленный в годы правления императорской династии Тан (VII - X вв) и Законы Великой династии Мин, составлен...
8409. Право Древнего Китая 30 KB
  Право Древнего Китая. В древнекитайском праве земля формально считалась государственной собственностью, но фактически ею владела община. Власть получала землю вместе с покоренным населением. Однако письменные свидетельства о купле - продаже зем...
8410. Древний Китай. История 57 KB
  Древний Китай История Древнего Китая ведет свое начало со II тысячелетия до н. э. Первые раннеклассовые общества возникли в бассейне р. Хуанхэ, здесь же появилась иероглифическая письменность-основной источник знаний о Древнем Китае. Характерная осо...