Kodowanie i dekodowanie podstawy 10 z C ++

Kodowanie i dekodowanie podstawy 10 z C ++
Base64 to zestaw znaków 64 znaków, w którym każda postać składa się z 6 bitów. Wszystkie te 64 znaki to znaki do wydruku. Postać jest symbolem. Tak więc każdy symbol podstawy 64 zestawu znaków składa się z 6 bitów. Takie sześć bitów nazywa się sekstetem. Bajt lub oket składa się z 8 bitów. Zestaw znaków ASCII składa się z 127 znaków, z których niektóre nie można drukować. Więc niektóre znaki zestawu znaków ASCII nie są symbolami. Symbol zestawu znaków ASCII składa się z 8 bitów.

Dane w komputerze są przechowywane w bajtach po 8 bitów każdy. Dane są wysyłane z komputera w bajtach po 8 bitów każdy. Dane są odbierane do komputera w bajtach po 8 bitów każdy.

Strumień bajtów można przekonwertować w strumień sekstetów (6 bitów na symbol). I to jest kodowanie Base64. Strumień sekstet można przekonwertować w strumień bajtów. I to jest dekodowanie base64. Innymi słowy, strumień znaków ASCII można przekonwertować w strumień symboli sekstetów. To jest kodowanie, a odwrotnie jest dekodowanie. Strumień symboli sekstetów, przekonwertowany ze strumienia symboli oktetu (bajt), jest dłuższy niż strumień symboli oktetów według liczby. Innymi słowy, strumień znaków Base64 jest dłuższy niż odpowiedni strumień znaków ASCII. Cóż, kodowanie do Base64 i dekodowanie z niej nie jest tak proste, jak po prostu wyrażone.

W tym artykule wyjaśniono kodowanie i dekodowanie Base64 z językiem komputerowym C ++. Pierwsza część artykułu wyjaśnia prawidłowe kodowanie i dekodowanie Base64. Druga część pokazuje, w jaki sposób niektóre funkcje C ++ można użyć do kodowania i dekodowania Base64. W tym artykule słowo „oktet” i „bajt” są używane zamiennie.

Treść artykułu

  • Przechodząc do bazy 64
  • Kodowanie bazy64
  • Nowa długość
  • Dekodowanie bazy 64
  • Błąd transmisji
  • Funkcje bitów C ++
  • Wniosek

Przechodząc do bazy 64

Alfabet lub zestaw znaków 2 symboli może być reprezentowany jednym bitem na symbol. Niech symbole alfabetu składają się z: zero i jednego. W tym przypadku zero to bit 0, a jeden to bit 1.

Alfabet lub zestaw znaków 4 symboli może być reprezentowany z dwoma bitami na symbol. Niech symbole alfabetu składają się z: 0, 1, 2, 3. W tej sytuacji 0 to 00, 1 to 01, 2 to 10, a 3 to 11.

Alfabet 8 symboli może być reprezentowany z trzema bitami na symbol. Niech symbole alfabetu składają się z: 0, 1, 2, 3, 4, 5, 6, 7. W tej sytuacji 0 to 000, 1 to 001, 2 to 010, 3 to 011, 4 to 100, 5 to 101, 6 to 110 i 7 to 111.

Alfabet 16 symboli może być reprezentowany z czterema bitami na symbol. Niech symbole alfabetu składają się z: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. W tej sytuacji 0 to 0000, 1 to 0001, 2 to 0010, 3 to 0011, 4 to 0100, 5 to 0101, 6 to 0110, 7 to 0111, 8 to 1000, 9 to 1001, a to 1010, b is 1011, C to 1100, D to 1101, E to 1110, a F to 1111.

Alfabet 32 ​​różnych symboli może być reprezentowany z pięcioma bitami na symbol.

To prowadzi nas do alfabetu 64 różnych symboli. Alfabet 64 różnych symboli może być reprezentowany z sześcioma bitami na symbol. Istnieje określony zestaw znaków 64 różnych symboli, zwany base64. W tym zestawie pierwsze 26 symboli to 26 wielkich liter angielskiego języka mówionego, w swoim porządku. Te 26 symboli to pierwsze liczby binarne od 0 do 25, gdzie każdy symbol to sekstet, sześć bitów. Kolejne liczby binarne od 26 do 51 to 26 małych liter angielskiego języka mówionego, w jego kolejności; Znowu każdy symbol, sekstet. Kolejne liczby binarne od 52 do 61 to 10 arabskich cyfr, w ich kolejności; Mimo to każdy symbol, sekstet.

Liczba binarna dla 62 jest dla symbolu +, a liczba binarna dla 63 jest dla symbolu / . Base64 ma różne warianty. Więc niektóre warianty mają różne symbole dla liczb binarnych 62 i 63.

Tabela Base64, pokazująca korespondencje dla indeksu, liczby binarnej i charakteru, to:

Alfabet Base64

Indeks Dwójkowy Zwęglać Indeks Dwójkowy Zwęglać Indeks Dwójkowy Zwęglać Indeks Dwójkowy Zwęglać
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 mi 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 mi 46 101110 u 62 111110 +
15 001111 P 31 011111 F 47 101111 v 63 111111 /

Wyściółka =

W rzeczywistości jest 65 symboli. Ostatni symbol jest =, którego liczba binarna nadal składa się z 6 bitów, czyli 111101. Nie jest sprzeczne z symbolem Base64 z 9 - patrz poniżej.

Kodowanie bazy64
Pole bitowe sekstet

Rozważ słowo:

pies

Istnieją trzy bajty ASCII dla tego słowa, które są:

01100100 01101111 01100111

Dołączył. Są to 3 oktety, ale składają się z 4 sekstetów w następujący sposób:

011001 000110 111101 100111

Z powyższej tabeli alfabetu Base64 te 4 sekstety są symbolami,

ZG9N

Zauważ, że kodowanie „psa” do bazy64 to „ZG9N”, co nie jest zrozumiałe.

Base64 koduje sekwencję 3 oktetów (bajtów) w sekwencję 4 sekstetów. 3 okety lub 4 sekstety to 24 bity.

Rozważ teraz następujące słowo:

To

Istnieją dwa oktety ASCII dla tego słowa, które są:

01101001 01110100

Dołączył. Są to 2 oktety, ale składają się z 2 sekstetów i 4 bitów. Strumień znaków Base64 składa się z sekstetów (6 bitów na znak). Tak więc dwa bity zerowe muszą być dołączone do tych 16 bitów, aby mieć 3 sekstety, to znaczy:

011010 010111 010000

To nie wszystko. Sekwencja Base64 składa się z 4 sekstetów na grupę; to znaczy 24 bity na grupę. Znak wyściółki = 111101. Dwa zerowe bity zostały już dołączone do 16 bitów, aby mieć 18 bitów. Tak więc, jeśli 6 bitów wyściółki znaku wyściółki zostanie dołączonych do 18 bitów, będą 24 bity w razie potrzeby. To jest:

011010 010111 010000 111101

Ostatnie sześć bitów ostatniego sekstetu to sekstet wyściółki, = . Te 24 bity składają się z 4 sekstetów, z czego ostatni, ale jeden sekstet ma pierwsze 4 bity symbolu Base64, a następnie dwa zerowe bity.

Teraz rozważ następujące słowo o jednej postaci:

I

Dla tego słowa jest jeden okT ASCII, czyli:

01001001

To jest 1 oktet, ale składa się z 1 sekstetu i 2 bitów. Strumień znaków Base64 składa się z sekstetów (6 bitów na znak). Tak więc cztery zerowe bity muszą być dołączone do tych 8 bitów, aby mieć 2 sekstety, to znaczy:

010010 010000

To nie wszystko. Sekwencja Base64 składa się z 4 sekstetów na grupę; to znaczy 24 bity na grupę. Znak wyściółki = 111101, który ma sześć bitów. Cztery bity zerowe zostały już dołączone do 8 bitów, aby mieć 12 bitów. To nie jest do czterech sekstetów. Zatem dwa kolejne sekstety wyściółki muszą zostać dołączone, aby zrobić 4 sekstety, to znaczy:

010010 010000 111101 111101

Strumień wyjściowy Base64

W programie należy wykonać szereg adwokatów alfabetu Base64, w którym indeks 0 ma charakter 8 bitów, a; Indeks 1 ma charakter 8 bitów, b; Indeks 2 ma charakter 8 bitów, C, aż wskaźnik 63 nie ma charakteru 8 bitów, / .

Tak więc wyjście dla słowa trzech znaków „pies” będzie „zg9n” czterech bajtów, wyrażony w bitach

01011010 01000111 00111001 01101110

gdzie Z jest 01011010 z 8 bitów; G to 01000111 z 8 bitów; 9 to 00111001 z 8 bitów, a n to 01101110 z 8 bitów. Oznacza to, że z trzech bajtów oryginalnego łańcucha wysyła się cztery bajty. Te cztery bajty są wartościami macierzy alfabetu Base64, gdzie każda wartość jest bajtem.

Wyjście dla słowa dwóch znaków „IT” będzie „axq =” z czterech bajtów, wyrażone w bitach jako

01100001 01011000 01010001 00111101

uzyskane z tablicy. Oznacza to, że z dwóch bajtów cztery bajty są nadal wyprowadzane.

Dane wyjściowe słowa jednej postaci „i” będzie „sq ==” z czterech bajtów, wyrażone w bitach jako

01010011 01010001 00111101 00111101

Oznacza to, że od jednego bajtu cztery bajty są nadal wyprowadzane.

Sekstet 61 (111101) jest wysyłany jako 9 (00111001). Sekstet = (111101) jest wysyłany jako = (00111101).

Nowa długość

Istnieją trzy sytuacje, które należy rozważyć, aby uzyskać oszacowanie nowej długości.

  • Oryginalna długość łańcucha to wielokrotność 3, e.G., 3, 6, 9, 12, 15 itp. W takim przypadku nowa długość będzie dokładnie 133.33% pierwotnej długości, ponieważ trzy oktety kończą jako cztery okety.
  • Oryginalna długość sznurka ma dwa bajty długości lub kończy się dwoma bajtami, po wielokrotności 3. W takim przypadku nowa długość będzie powyżej 133.33% pierwotnej długości, ponieważ część sznurka dwóch oktetów kończy się czterem.
  • Oryginalna długość łańcucha ma jeden bajt długości lub kończy się jednym bajtem po wielokrotności 3. W takim przypadku nowa długość będzie powyżej 133.33% pierwotnej długości (więcej powyżej niż w poprzednim przypadku), ponieważ część sznurka jednego oktetu kończy się czterema oketami.

Maksymalna długość linii

Po przejściu z oryginalnego ciągu przez tablicę alfabetu Base64 i kończąc na oktetach co najmniej 133.33% długości, żaden ciąg wyjściowy nie musi mieć dłuższego niż 76 oketów. Gdy ciąg wyjściowy ma 76 znaków, przed kolejnymi 76 oktetów należy dodać nową postać. Długi ciąg wyjściowy ma wszystkie sekcje, składające się z 76 znaków, z wyjątkiem ostatnich, jeśli nie jest to do 76 znaków. Używający programistów separatora linii jest prawdopodobnie nowym znakiem „\ n”; ale ma to być „\ r \ n”.

Dekodowanie bazy 64

Do dekodowania, wykonaj odwrotność kodowania. Użyj następującego algorytmu:

  • Jeśli odbierany ciąg jest dłuższy niż 76 znaków (oktety), podziel długi ciąg na szereg strun, usuwając separator linii, który może być „\ r \ n” lub „\ n”.
  • Jeśli istnieje więcej niż jedna linia po 76 znaków, oznacza to wszystkie linie, z wyjątkiem ostatnich grup po czterech znakach. Każda grupa spowoduje trzy znaki przy użyciu tablicy alfabetowej Base64. Cztery bajty muszą zostać przekonwertowane na sześć sekstetów, zanim zostaną przekonwertowane na trzy okety.
  • Ostatnia linia lub jedyna linia, jaką mógł mieć ciąg, wciąż składa się z grup czterech znaków. Ostatnia grupa czterech znaków może skutkować jednym lub dwoma znakami. Wiedzieć, czy ostatnia grupa czterech znaków spowoduje jeden znak, sprawdź, czy ostatnie dwa oktety grupy to każde ASCII, =. Jeśli grupa daje dwa znaki, to tylko ostatni okett powinien być ASCII, =. Każda czterokrotna sekwencja znaków przed ostatnią czterokrotną sekwencją jest obsługiwana jak w poprzednim kroku.

Błąd transmisji

Na końcu odbiorczym dowolna znak inna niż znak separacji linii lub znaki, które nie są wartością tablicy alfabetu Base64, wskazuje błąd transmisji; i należy się obsługiwać. Obsługa błędów transmisji nie jest adresowana w tym artykule. Uwaga: Obecność bajtu, = wśród 76 znaków, nie jest błędem transmisji.

Funkcje bitów C ++

Fundamentalni członkowie elementu struktury mogą otrzymać wiele bitów innych niż 8. Poniższy program ilustruje to:

#włączać
za pomocą przestrzeni nazw Std;
struct s3
niepodpisany int A: 6;
niepodpisany int b: 6;
niepodpisany int c: 6;
niepodpisany int d: 6;
s3;
int main ()

S3.a = 25;
S3.B = 6;
S3.c = 61;
S3.D = 39;
Cout<powrót 0;

Wyjście to:

25, 6, 61, 39

Wyjściowe liczby całkowite są przypisane. Jednak każdy zajmuje 6 bitów w pamięci, a nie 8 lub 32 bity. Zwróć uwagę, w jaki sposób liczba bitów jest przypisywana w deklaracji z okrężnicą.

Wyodrębnienie pierwszych 6 bitów z oktetu

C ++ nie ma funkcji ani operatora do wyodrębnienia pierwszego zestawu bitów z oktetu. Aby wyodrębnić pierwsze 6 bitów, przesunięcie w prawo zawartość oktetu o 2 miejsca. Opuszczone dwa bity na lewym końcu są wypełnione zerami. Powstały okett, który powinien być niepodpisanym znakiem, jest teraz liczbą całkowitą, reprezentowaną przez pierwsze 6 bitów okTETU. Następnie przypisz wynikowy oket do elementu struktury pola bitowego 6 bitów. Prawidłowy operator zmiany jest >>, nie należy mylić z operatorem ekstrakcji obiektu Cout.

Zakładając, że element Struct 6 pola bitowego jest, S3.a, następnie pierwsze 6 bitów postaci „D” jest wyodrębnione w następujący sposób:

niepodpisany char cH1 = „d”;
CH1 = CH1 >> 2;
S3.a = CH1;

Wartość S3.A można teraz użyć do indeksowania tablicy alfabetu Base64.

Produkcja drugiego sekstetu z 3 znaków

Drugie sześć bitów składa się z dwóch ostatnich bitów pierwszego okttu i następnych 4 bitów drugiego okttu. Chodzi o to, aby przenieść dwa ostatnie bity na piątą i szóstą pozycję okt. I uczynić resztę bitów okTETU zero; Potem niewiele i to z pierwszymi czterem.

Przemieszczenie lewej ostatnie dwa bity do piątej i szóstej pozycji wykonuje operator butowy w lewo, <<, which is not to be confused with the cout insertion operator. The following code segment left-shifts the last two bits of 'd' to the fifth and sixth positions:

niepodpisany char i = 'd';
i = i <<4;

W tym momencie zwolnione bity zostały wypełnione zerami, podczas gdy nieaktywne przesunięte bity, które nie są wymagane. Aby reszta bitów w i zero, muszę być pod względem butowym i z 00110000, czyli liczbą całkowitą, 96. Robi to następujące stwierdzenie:

I = I i 96;

Poniższy segment kodu przesuwa pierwsze cztery bity drugiego oktetu do ostatnich czterech pozycji:

niepodpisany Char J = „O”;
j = j >> 4;

Opuszczone kawałki zostały wypełnione zerami. W tym momencie mam 8 bitów, a J ma 8 bitów. Wszystkie 1 w tych dwóch niepodpisanych znakach są teraz na właściwych pozycjach. Aby zdobyć char, w drugim sekstiecie, te dwa 8-bitowe znaki muszą być pod względem niewielkim i, w następujący sposób:

niepodpisany char cH2 = i & j;

CH2 nadal ma 8 bitów. Aby uczynić go sześć bitów, należy go przypisać do członka struktury pola bitowego 6 bitów. Jeśli element struktury pola bitowego to S3.B, wówczas zadanie zostanie wykonane w następujący sposób:

S3.B = CH2;

Odtąd, S3.B będzie używane zamiast CH2 do indeksowania tablicy alfabetu Base64.

Dodawanie dwóch zer do trzeciego sekstetu

Gdy sekwencja do zakodowania ma dwa znaki, trzeci sekstet należy dodać dwa zera. Załóżmy, że oktet jest już prefiksowany przez dwa zerowe bity, a kolejne cztery bity to właściwe bity. Aby zrobić dwa ostatnie bity tego oktetu, dwa zer, butowe i okettowe z 11111100, czyli liczbą całkowitą, 252. Robi to następujące stwierdzenie:

niepodpisany Char CH3 = oktet i 252;

CH3 ma teraz wszystkie ostatnie sześć bitów, które są wymaganymi bitami, choć nadal składa się z 8 bitów. Aby uczynić go sześć bitów, należy go przypisać do członka struktury pola bitowego 6 bitów. Jeśli element struktury pola bitowego to S3.C, wówczas zadanie zostanie wykonane w następujący sposób:

S3.C = CH3;

Odtąd, S3.C będzie używane zamiast CH2 do indeksowania tablicy alfabetu Base64.

Resztę obsługi bitów można wykonać jak wyjaśniono w tym rozdziale.

Base64 Tablica alfabetowa

Do kodowania tablica powinna być coś w rodzaju,

unsigned char arr [] = 'a', 'b', 'c', - - - '/';

Dekodowanie jest procesem odwrotnym. Tak więc do tej struktury powinna być używana mapa nieuporządkowana, coś w rodzaju,

UNOPORDED_MAP umap = 'a', 0, 'b', 1, 'c', 2, - - - '/', 63;

Klasa String

Klasa stringowa powinna być używana do całkowitej niezakodowanych i zakodowanych sekwencji. Reszta programowania to normalne programowanie C ++.

Wniosek

Base64 to zestaw znaków 64 znaków, w którym każda postać składa się z 6 bitów. Do kodowania każde trzy-bajtowe oryginalnego ciągu jest przekonwertowane na cztery sekstety po 6 bitów. Te sekstety są używane jako indeksy dla tabeli alfabetu Base64 do kodowania. Jeśli sekwencja składa się z dwóch znaków, cztery sekstety są nadal uzyskiwane, z ostatnim sekstetem, będąc numerem 61. Jeśli sekwencja składa się z jednej postaci, nadal uzyskuje się cztery sekstety, z dwoma ostatnimi sekstetami, które są dwa z liczby 61.

Dekodowanie robi odwrotność.