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
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.
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:
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_MAPumap = '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ść.