4883

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

Лекция

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

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

Русский

2012-11-28

41.5 KB

54 чел.

Кодирование данных. Алгоритм 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");

}


 

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

58643. Как надо действовать, чтобы правильно написать безударную гласную 55 KB
  Цель: Развитие умения работать по алгоритму чтобы правильно писать безударную гласную в корне слова познакомить с новым значением омонимы воспитывать самостоятельность пополнять словарный запас.
58645. Склонение личных местоимений в единственном и множественном числе 56 KB
  Цели: образовательные: совершенствовать умение склонять личные местоимения в единственном и множественном числе употреблять их в речи; развивающие: развивать орфографическую зоркость внимание мышление память...
58648. Формирование синтаксических умений при разборе простого и сложного предложения на грамматическом уровне развития речи младших школьников на уроках русского языка 58 KB
  Синтаксический анализ предложения. Из предложения текста: Крепкий лёд незаметно сковал реку. Назвать сочетание слов которое не является словосочетанием определить и охарактеризовать грамматическую основу предложения лёд сковывает А теперь давайте поиграем.
58649. Письменный пересказ текста-рассуждение 45.5 KB
  Задачи: образовательные Моделировать интонационный состав высказывания Составлять высказывание по опорным вопросам Участвовать в учебном диалоге: отвечать на вопрос задавать вопрос Создавать план текста. Осознавать особенности каждого типа текста.
58651. Урок развития и культуры речи. Национальные костюмы 33.5 KB
  Цель: Развивать навыки чтения, умения объяснять значение слов, исходя из контекста (словарь); работать над устным сочинением-описанием по картине. Повторить и обсудить изученный материал по теме Состав слова. Орфография