- Спойлер
- /* Кодирование данных. Алгоритм 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
Источник: http://5fan.ru/wievjob.php?id=4883