Кодирование и декодирование Base64 с помощью C++

Как преобразовать строку в int в C++ Изучение

Base64 — это набор символов из 64 символов, каждый из которых состоит из 6 бит. Все эти 64 символа являются печатными. Персонаж — это символ. Таким образом, каждый символ набора символов base 64 состоит из 6 бит. Такие шесть битов называются секстетом. Байт или октет состоит из 8 бит. Набор символов ASCII состоит из 127 символов, некоторые из которых не печатаются. Таким образом, некоторые символы набора символов ASCII не являются символами. Символ для набора символов ASCII состоит из 8 бит.

Данные в компьютере хранятся в байтах по 8 бит каждый.

Поток байтов можно преобразовать в поток секстетов (6 бит на символ). И это кодировка base64. Поток секстетов можно преобразовать в поток байтов. И это декодирование base64. Другими словами, поток символов ASCII может быть преобразован в поток символов секстета. Это кодирование, а обратное — декодирование. Поток символов секстета, преобразованный из потока символов октета (байта), по номеру длиннее потока символов октета. Другими словами, поток символов base64 длиннее, чем соответствующий поток символов ASCII. Ну, кодирование в base64 и декодирование из него не так просто, как только что выразилось.

В этой статье объясняется кодирование и декодирование Base64 с помощью компьютерного языка C ++. В первой части статьи объясняется правильное кодирование и декодирование base64. Во второй части показано, как можно использовать некоторые функции C ++ для кодирования и декодирования base64. В этой статье слова «октет» и «байт» используются как синонимы.

Переход на Base 64

Алфавит или набор символов из 2 символов может быть представлен одним битом на символ. Пусть символы алфавита состоят из нуля и единицы. В этом случае ноль — это бит 0, а единица — это бит 1.

Алфавит или набор символов из 4 символов может быть представлен двумя битами на символ. Пусть символы алфавита состоят из: 0, 1, 2, 3. В этой ситуации 0 равно 00, 1 равно 01, 2 равно 10, а 3 равно 11.

Читайте также:  Как управлять macOS с помощью Python?

Алфавит из 8 символов может быть представлен тремя битами на символ. Пусть символы алфавита состоят из: 0, 1, 2, 3, 4, 5, 6, 7. В этой ситуации 0 — 000, 1 — 001, 2 — 010, 3 — 011, 4 — 100, 5 — 101., 6 — 110 и 7 — 111.

Алфавит из 16 символов может быть представлен четырьмя битами на символ. Пусть символы алфавита состоят из: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. В этой ситуации 0 — это 0000, 1 — 0001., 2 — 0010, 3 — 0011, 4 — 0100, 5 — 0101, 6 — 0110, 7 — 0111, 8 — 1000, 9 — 1001, A — 1010, B — 1011, C — 1100, D — 1101, E равно 1110, а F — 1111.

Алфавит из 32 различных символов может быть представлен пятью битами на символ.

Это приводит нас к алфавиту из 64 различных символов. Алфавит из 64 различных символов может быть представлен шестью битами на символ. Существует особый набор символов из 64 различных символов, называемый base64. В этом наборе первые 26 символов — это 26 заглавных букв разговорного английского языка в указанном порядке. Эти 26 символов представляют собой первые двоичные числа от 0 до 25, где каждый символ представляет собой секстет из шести битов. Следующие двоичные числа от 26 до 51 — это 26 строчных букв английского разговорного языка в их порядке; опять же, каждый символ, секстет. Следующие двоичные числа от 52 до 61 — это 10 арабских цифр в их порядке; тем не менее, каждый символ — секстет.

Двоичное число 62 соответствует символу +, а двоичное число 63 — символу /. У Base64 есть разные варианты. Таким образом, некоторые варианты имеют разные символы для двоичных чисел 62 и 63.

Таблица base64, показывающая соответствия индекса, двоичного числа и символа:

Алфавит Base64

Index Binary Char Index Binary Char Index Binary Char Index Binary Char
0 000000 A 16 010000 Q 32 100000 g 48 110000 w
1 000001 B 17 010001 R 33 100001 h 49 110001 x
2 000010 C 18 010010 S 34 100010 i 50 110010 y
3 000011 D 19 010011 T 35 100011 j 51 110011 z
4 000100 E 20 010100 U 36 100100 k 52 110100 0
5 000101 F 21 010101 V 37 100101 l 53 110101 1
6 000110 G 22 010110 W 38 100110 m 54 110110 2
7 000111 H 23 010111 X 39 100111 n 55 110111 3
8 001000 I 24 011000 Y 40 101000 o 56 111000 4
9 001001 J 25 011001 Z 41 101001 p 57 111001 5
10 001010 K 26 011010 a 42 101010 q 58 111010 6
11 001011 L 27 011011 b 43 101011 r 59 111011 7
12 001100 M 28 011100 c 44 101100 s 60 111100 8
13 001101 N 29 011101 d 45 101101 t 61 111101 9
14 001110 O 30 011110 e 46 101110 u 62 111110 +
15 001111 P 31 011111 f 47 101111 v 63 111111 /

Padding =

На самом деле символов 65. Последним символом является =, двоичное число которого по-прежнему состоит из 6 битов, то есть 111101. Он не конфликтует с символом base64, равным 9 — см. Ниже.

Кодирование битовых полей Sextet Base64

Рассмотрим слово:

    dog

Это слово состоит из трех байтов ASCII:

    01100100 01101111 01100111

присоединился. Это 3 октета, но они состоят из 4 секстетов следующим образом:

    011001 000110 111101 100111

Из приведенной выше таблицы алфавита base64 эти 4 секстета являются символами,

    ZG9n

Обратите внимание, что кодировка «dog» в base64 — «ZG9n», что непонятно.

Base64 кодирует последовательность из 3 октетов (байтов) в последовательность из 4 секстетов. 3 октета или 4 секстета составляют 24 бита.

Рассмотрим теперь следующее слово:

    it

Для этого слова есть два октета ASCII:

    01101001 01110100

присоединился. Это 2 октета, но они состоят из 2 секстетов и 4 битов. Поток символов base64 состоит из секстетов (6 бит на символ). Итак, к этим 16 битам нужно добавить два нулевых бита, чтобы получить 3 секстета, то есть:

    011010 010111 010000

Это еще не все. Последовательность Base64 состоит из 4 секстетов на группу; то есть 24 бита на группу. Знак заполнения = 111101. Два нулевых бита уже добавлены к 16 битам, чтобы получить 18 бит. Таким образом, если 6 битов заполнения символа заполнения добавляются к 18 битам, то при необходимости будет 24 бита. То есть:

    011010 010111 010000 111101

Последние шесть битов последнего секстета — это дополнительный секстет =. Эти 24 бита состоят из 4 секстетов, из которых предпоследний секстет имеет первые 4 бита символа base64, за которыми следуют два нулевых бита.

Теперь рассмотрим следующее односимвольное слово:

I

Для этого слова есть один октет ASCII:

    01001001

Это 1 октет, но состоит из 1 секстета и 2 бит. Поток символов base64 состоит из секстетов (6 бит на символ). Итак, к этим 8 битам нужно добавить четыре нулевых бита, чтобы получить 2 секстета, то есть:

    010010 010000

Это еще не все. Последовательность Base64 состоит из 4 секстетов на группу; то есть 24 бита на группу. Знак заполнения = 111101, что составляет шесть битов. К 8 битам уже добавлено четыре нулевых бита, чтобы получить 12 бит. Это не до четырех секстетов. Итак, нужно добавить еще два дополнительных секстета, чтобы получилось 4 секстета, а именно:

    010010 010000 111101 111101

Выходной поток Base64

В программе должен быть составлен массив символов алфавита base64, где индекс 0 имеет символ из 8 бит, A; индекс 1 имеет разряд 8 бит, B; индекс 2 имеет символ из 8 бит, C, до тех пор, пока индекс 63 не станет символом из 8 бит, /.

Таким образом, на выходе для слова из трех символов «собака» будет «ZG9n» из четырех байтов, выраженных в битах как

    01011010 01000111 00111001 01101110

где Z — 01011010 из 8 бит; G — 01000111 из 8 бит; 9 — это 00111001 из 8 бит, а n — это 01101110 из 8 бит. Это означает, что из трех байтов исходной строки выводятся четыре байта. Эти четыре байта являются значениями массива алфавита base64, где каждое значение является байтом.

На выходе для слова из двух символов «it» будет «aXQ =» из четырех байтов, выраженное в битах как

    01100001 01011000 01010001 00111101

полученный из массива. Это означает, что из двух байтов по-прежнему выводятся четыре байта.

Для слова из одного символа «I» выводом будет «SQ ==» из четырех байтов, выраженное в битах как

    01010011 01010001 00111101 00111101

Это означает, что из одного байта по-прежнему выводятся четыре байта.

Секстет 61 (111101) выводится как 9 (00111001). Секстет = (111101) выводится как = (00111101).

Новая длина

Здесь необходимо рассмотреть три ситуации, чтобы оценить новую длину.

  • Исходная длина строки кратна 3, например, 3, 6, 9, 12, 15 и т. Д. В этом случае новая длина будет ровно 133,33% от исходной длины, потому что три октета в итоге составляют четыре октета.
  • Исходная длина строки составляет два байта или заканчивается двумя байтами после числа, кратного 3. В этом случае новая длина будет выше 133,33% от исходной длины, потому что часть строки из двух октетов заканчивается как четыре октета.
  • Исходная длина строки составляет один байт или заканчивается одним байтом после числа, кратного 3. В этом случае новая длина будет выше 133,33% исходной длины (больше, чем в предыдущем случае), потому что Строковая часть одного октета становится четырьмя октетами.

Максимальная длина линии

После перехода от исходной строки к массиву алфавита base64 и получения октетов длиной не менее 133,33% ни одна строка вывода не должна быть длиннее 76 октетов. Если длина выходной строки составляет 76 символов, необходимо добавить символ новой строки до того, как будут добавлены еще 76 октетов, или будет добавлено меньше символов. В длинной выходной строке есть все разделы, состоящие из 76 символов каждый, кроме последнего, если его длина не превышает 76 символов. Программисты-разделители строк, скорее всего, используют символ новой строки ’\ n’; но предполагается, что это «\ r \ n».

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

Для декодирования выполните обратное кодирование. Используйте следующий алгоритм:

  • Если полученная строка длиннее 76 символов (октетов), разделите длинную строку на массив строк, удалив разделитель строк, который может быть «\ r \ n» или «\ n».
  • Если имеется более одной строки по 76 символов в каждой, то это означает, что все строки, кроме последней, состоят из групп по четыре символа в каждой. Каждая группа приведет к трем символам, используя массив алфавита base64. Четыре байта необходимо преобразовать в шесть секстетов перед преобразованием в три октета.
  • Последняя строка или единственная строка, которая могла быть в строке, по-прежнему состоит из групп по четыре символа. Последняя группа из четырех символов может привести к одному или двум символам. Чтобы узнать, приведет ли последняя группа из четырех символов к одному символу, проверьте, являются ли последние два октета группы каждым ASCII, =. Если группа дает два символа, тогда только последний октет должен быть ASCII, =. Любая четырехкратная последовательность символов перед этой последней четырехкратной последовательностью обрабатывается так же, как на предыдущем шаге.

Ошибка передачи

На принимающей стороне любой символ, кроме символа разделения строк или символов, который не является значением массива алфавита base64, указывает на ошибку передачи; и с ними нужно обращаться. В этой статье не рассматривается обработка ошибок передачи. Примечание. Наличие байта = среди 76 символов не является ошибкой передачи.

Возможности C ++ Bit

Фундаментальным членам элемента структуры может быть присвоено число битов, отличное от 8. Следующая программа иллюстрирует это:

#include <iostream>

using namespace std;

struct S3 {

unsigned int a:6;

unsigned int b:6;

unsigned int c:6;

unsigned int d:6;

}s3;

int main()

{

s3.a = 25;

s3.b = 6;

s3.c = 61;

s3.d = 39;

cout<<s3.a<<«, «<<s3.b<<«, «<<s3.c<<«, «<<s3.d <<endl;

return 0;

}

Результат:

    2566139

Выходные целые числа соответствуют назначению. Однако каждый из них занимает в памяти 6 бит, а не 8 или 32 бита. Обратите внимание, как количество битов в объявлении назначается двоеточием.

Извлечение первых 6 бит из октета

В C ++ нет функции или оператора для извлечения первого набора битов из октета. Чтобы извлечь первые 6 битов, сдвиньте содержимое октета вправо на 2 разряда. Освободившиеся два бита на левом конце заполняются нулями. Результирующий октет, который должен быть беззнаковым символом, теперь является целым числом, представленным первыми 6 битами октета. Затем присвойте полученный октет элементу структурного битового поля из 6 бит. Оператор сдвига вправо — >>, не путать с оператором извлечения объекта cout.

Предполагая, что членом битового поля структуры 6 является s3.a, тогда первые 6 битов символа ’d’ извлекаются следующим образом:

   unsigned char ch1 = ‘d’;

ch1 = ch1 >>2;

s3.a = ch1;

Значение s3.a теперь можно использовать для индексации массива алфавита base64.

Создание второго секстета из 3-х иероглифов

Вторые шесть битов состоят из двух последних бит первого октета и следующих 4 бит второго октета. Идея состоит в том, чтобы поместить последние два бита в пятую и шестую позиции своего октета, а остальные биты октета сделать нулевыми; затем побитовое И с первыми четырьмя битами второго октета, который был сдвинут вправо до его конца.

Сдвиг влево двух последних битов в пятую и шестую позиции выполняется оператором побитового сдвига влево <<, который не следует путать с оператором вставки cout. Следующий сегмент кода сдвигает влево два последних бита буквы d на пятую и шестую позиции:

    unsigned char i = ‘d’;

= i <<4;

На этом этапе освобожденные биты были заполнены нулями, в то время как неосвобожденные сдвинутые биты, которые не требуются, все еще присутствуют. Чтобы остальные биты в i были равны нулю, i должен быть побитовым И с 00110000, которое является целым числом 96. Это делает следующий оператор:

    i = i & 96;

Следующий сегмент кода сдвигает первые четыре бита второго октета на последние четыре битовых позиции:

    unsigned char j = ‘o’;

= j >>4;

Освободившиеся биты заполнены нулями. На данный момент у i 8 бит, а у j 8 бит. Все 1 в этих двух беззнаковых символах теперь находятся на своих правильных позициях. Чтобы получить символ для второго секстета, эти два 8-битных символа должны быть побитовыми И, как показано ниже:

    unsigned char ch2 = i & j;

ch2 по-прежнему имеет 8 бит. Чтобы сделать его шестибитным, он должен быть назначен члену структурного битового поля из 6 бит. Если членом битового поля структуры является s3.b, то присвоение будет выполнено следующим образом:

     s3.b = ch2;

Отныне s3.b будет использоваться вместо ch2 для индексации массива алфавита base64.

Добавление двух нулей для третьего секстета

Когда кодируемая последовательность состоит из двух символов, к третьему секстету нужно добавить два нуля. Предположим, что октету уже предшествуют два нулевых бита, а следующие четыре бита являются правыми битами. Чтобы сделать последние два бита этого октета двумя нулями, побитовым И октетом с 11111100, которое является целым числом, 252. Следующий оператор делает это:

    unsigned char ch3 = octet & 252;

ch3 теперь имеет все последние шесть бит, которые являются обязательными битами, хотя он по-прежнему состоит из 8 бит. Чтобы сделать его шестибитным, он должен быть назначен члену структурного битового поля из 6 бит. Если членом битового поля структуры является s3.c, то присвоение будет выполнено следующим образом:

     s3.c = ch3;

Отныне s3.c будет использоваться вместо ch2 для индексации массива алфавита base64.

Остальная часть обработки битов может быть выполнена, как описано в этом разделе.

Алфавитный массив Base64

Для кодирования массив должен быть примерно таким,

    unsigned char arr[] = {‘A’‘B’‘C’   ‘/’};

Декодирование — это обратный процесс. Итак, для этой структуры следует использовать неупорядоченную карту, например,

    unordered_map<unsigned charunsigned char> umap = {{‘A’0}{‘B’1}{‘C’2}   {‘/’63}};

Класс String

Класс строки должен использоваться для всех некодированных и закодированных последовательностей. Остальное программирование — это обычное программирование на C ++.

Заключение

Base64 — это набор символов из 64 символов, каждый из которых состоит из 6 бит. Для кодирования каждые три байта исходной строки преобразуются в четыре секстета по 6 бит каждый. Эти секстеты используются в качестве индексов для таблицы алфавита base64 для кодирования. Если последовательность состоит из двух символов, все равно получается четыре секстета, причем последний секстет — это число 61. Если последовательность состоит из одного символа, все равно получаются четыре секстета, причем последние два секстета являются двумя из числа 61.

Оцените статью
bestprogrammer.ru
Добавить комментарий