Codierung und Dekodierung von Basetop 10 mit C ++

Codierung und Dekodierung von Basetop 10 mit C ++
Base64 ist ein Zeichensatz von 64 Zeichen, wobei jedes Zeichen aus 6 Bit besteht. Alle diese 64 Zeichen sind druckbare Zeichen. Ein Charakter ist ein Symbol. Jedes Symbol der Basis 64 -Zeichenset besteht also aus 6 Bits. Solche sechs Bits werden als Sextett bezeichnet. Ein Byte oder ein Oktett besteht aus 8 Bits. Das ASCII -Zeichensatz besteht aus 127 Zeichen, von denen einige nicht druckbar sind. Einige Zeichen des ASCII -Zeichensatzes sind also keine Symbole. Ein Symbol für das ASCII -Zeichensatz besteht aus 8 Bits.

Daten im Computer werden in jeweils 8 Bit in Bytes gespeichert. Daten werden aus dem Computer in Bytes von jeweils 8 Bits gesendet. Daten werden in den Computer in Bytes von jeweils 8 Bit empfangen.

Ein Strom von Bytes kann in einen SEXTET -Strom (6 Bit pro Symbol) umgewandelt werden. Und das ist Basis64 -Codierung. Ein Stream von Sextetten kann in einen Strom von Bytes umgewandelt werden. Und das ist Basis64 -Dekodierung. Mit anderen Worten kann ein Strom von ASCII -Zeichen in einen Strom von Sextettsymbolen umgewandelt werden. Dies ist codierend, und das Gegenteil ist dekodiert. Der Stream der Sextettsymbole, der aus einem Stream von Oktettsymbolen (Byte) konvertiert wird, ist länger als der Strom der Oktettsymbole nach Zahl. Mit anderen Worten, ein Strom von Basis64 -Zeichen ist länger als der entsprechende Strom von ASCII -Zeichen. Nun, kodieren in Base64 und das Dekodieren daraus ist nicht so einfach, wie gerade ausgedrückt.

Dieser Artikel erläutert die Codierung und Dekodierung von Base64 mit der C ++ - Computersprache. Der erste Teil des Artikels erklärt Base64 Codierung und Dekodierung richtig. Der zweite Teil zeigt, wie einige C ++ - Funktionen zum Codieren und Dekodieren von Base64 verwendet werden können. In diesem Artikel werden das Wort "Oktett" und "Byte" austauschbar verwendet.

Artikelinhalt

  • Auf die Basis 64 bewegen
  • Codierung Basis64
  • Neue Länge
  • Decoding Base64
  • Übertragungsfehler
  • C ++ - Bitfunktionen
  • Abschluss

Auf die Basis 64 bewegen

Ein Alphabet oder ein Zeichensatz von 2 Symbolen kann mit einem Bit pro Symbol dargestellt werden. Lassen Sie die Alphabetsymbole bestehen aus: Null und eins. In diesem Fall ist Null Bit 0 und einer Bit 1.

Ein Alphabet oder ein Zeichensatz von 4 Symbolen kann mit zwei Bits pro Symbol dargestellt werden. Lassen Sie die Alphabetsymbole bestehen aus: 0, 1, 2, 3. In dieser Situation ist 0 00, 1 ist 01, 2 ist 10 und 3 11 ist 11.

Ein Alphabet von 8 Symbolen kann mit drei Bit pro Symbol dargestellt werden. Lassen Sie die Alphabetsymbole bestehen aus: 0, 1, 2, 3, 4, 5, 6, 7. In dieser Situation ist 0 000, 1 ist 001, 2 ist 010, 3 ist 011, 4 IS 100, 5 IS 101, 6 IS 110 und 7 IS 111.

Ein Alphabet von 16 Symbolen kann mit vier Bit pro Symbol dargestellt werden. Lassen Sie die Alphabetsymbole bestehen aus: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. In dieser Situation ist 0 0000, 1 ist 0001, 2 ist 0010, 3 ist 0011, 4 ist 0100, 5 ist 0101, 6 IS 0110, 7 IS 0111, 8 IS 1000, 9 IS 1001, A IS 1010, B IS 1011, c ist 1100, d ist 1101, e ist 1110 und f ist 1111.

Ein Alphabet von 32 verschiedenen Symbolen kann mit fünf Bit pro Symbol dargestellt werden.

Dies führt uns zu einem Alphabet von 64 verschiedenen Symbolen. Ein Alphabet von 64 verschiedenen Symbole kann mit sechs Bits pro Symbol dargestellt werden. Es gibt einen bestimmten Zeichensatz von 64 verschiedenen Symbolen, die als Base64 bezeichnet werden. In diesem Satz sind die ersten 26 Symbole die 26 Großbuchstaben der englischen gesprochenen Sprache in ihrer Reihenfolge. Diese 26 Symbole sind die ersten Binärzahlen von 0 bis 25, wobei jedes Symbol ein Sextett ist, sechs Bits. Die nächsten Binärzahlen von 26 bis 51 sind die 26 Kleinbuchstaben der englischen gesprochenen Sprache in ihrer Reihenfolge; Wieder jedes Symbol, ein Sextett. Die nächsten Binärzahlen von 52 bis 61 sind die 10 arabischen Ziffern in ihrer Reihenfolge; Trotzdem jedes Symbol, ein Sextett.

Die Binärzahl für 62 ist für das Symbol +und die Binärzahl für 63 für das Symbol / ist . Base64 hat unterschiedliche Varianten. Einige Varianten haben also unterschiedliche Symbole für die binäre Anzahl von 62 und 63.

Die Tabelle Base64, die Korrespondenzen für Index, Binärzahl und Zeichen zeigt, lautet:

Das Basis64 -Alphabet

Index Binär Verkohlen Index Binär Verkohlen Index Binär Verkohlen Index Binär Verkohlen
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 ich 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 ICH 24 011000 Y 40 101000 Ö 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 Ö 30 011110 e 46 101110 u 62 111110 +
15 001111 P 31 011111 F 47 101111 v 63 111111 /

Polsterung =

Es gibt tatsächlich 65 Symbole. Das letzte Symbol ist =, dessen binäre Zahl immer noch aus 6 Bit besteht, was 111101 ist. Es widerspricht nicht dem Symbol von Base64 von 9 - siehe unten.

Codierung Basis64
Sextett-Bitfelder

Betrachten Sie das Wort:

Hund

Es gibt drei ASCII -Bytes für dieses Wort, nämlich:

01100100 01101111 01100111

beigetreten. Dies sind 3 Oktetten, bestehen jedoch aus 4 Sextetten wie folgt:

011001 000110 111101 100111

Aus der obigen Basis64 -Alphabet -Tabelle sind diese 4 Sextets die Symbole,

ZG9N

Beachten Sie, dass die Codierung von „Hund“ in Base64 „ZG9N“ ist, was nicht verständlich ist.

Base64 codiert eine Sequenz von 3 Oktetten (Bytes) in eine Sequenz von 4 Sextets. 3 Oktetten oder 4 Sextetten sind 24 Bit.

Betrachten Sie jetzt das folgende Wort:

Es

Es gibt zwei ASCII -Oktetten für dieses Wort, nämlich:

01101001 01110100

beigetreten. Dies sind 2 Oktetten, bestehen jedoch aus 2 Sextetten und 4 Bits. Ein Stream von Base64 -Zeichen besteht aus Sextets (6 Bit pro Zeichen). Daher müssen zwei Null -Bits an diese 16 Bits angehängt werden, um 3 Sextets zu haben, dh:

011010 010111 010000

Das ist nicht alles. Base64 -Sequenz besteht aus 4 Sextetten pro Gruppe; das heißt, 24 Bit pro Gruppe. Das Polstercharakter = ist 111101. Zwei Null -Bits wurden bereits an die 16 Bit angehängt, um 18 Bit zu haben. Wenn also die 6 Polsterbits des Polstercharakters an die 18 Bit angehängt sind, werden nach Bedarf 24 Bit bestehen. Das ist:

011010 010111 010000 111101

Die letzten sechs Teile des letzten Sextetts sind das Polstersextett = = . Diese 24 Bit bestehen aus 4 Sextetten, von denen das letzte, aber eins Sextett die ersten 4 Bit des Base64-Symbols hat, gefolgt von zwei Nullbits.

Betrachten Sie nun das folgende ein Charakterwort:

ICH

Es gibt einen ASCII -Oktett für dieses Wort, nämlich:

01001001

Dies ist 1 Oktett, besteht aber aus 1 Sextett und 2 Bits. Ein Stream von Base64 -Zeichen besteht aus Sextets (6 Bit pro Zeichen). Daher müssen vier Null -Bits an diese 8 Bits angehängt werden, um 2 Sextets zu haben, dh:

010010 010000

Das ist nicht alles. Base64 -Sequenz besteht aus 4 Sextetten pro Gruppe; das heißt, 24 Bit pro Gruppe. Das Polstercharakter = ist 111101, was sechs Bits lang ist. Es wurden bereits vier Null -Bits an die 8 Bit angehängt, um 12 Bit zu haben. Dies sind bis zu vier Sextetten nicht. Daher müssen zwei weitere Polstersextets angehängt werden, um 4 Sextets zu erstellen, dh:

010010 010000 111101 111101

Ausgangsstrom von Base64

Im Programm muss ein Array-of-Care of the Base64-Alphabet hergestellt werden, wobei Index 0 den Charakter von 8 Bits hat, a; Index 1 hat den Charakter von 8 Bit, b; Index 2 hat das Zeichen von 8 Bit, c, bis Index 63 das Zeichen von 8 Bits hat, / .

Die Ausgabe für das Wort von drei Zeichen, "Hund", wird also "Zg9n" von vier Bytes sein, die in Bits als ausgedrückt werden

01011010 01000111 00111001 01101110

wobei z 01011010 von 8 Bit ist; G ist 01000111 von 8 Bit; 9 ist 00111001 von 8 Bit und N ist 01101110 von 8 Bits. Dies bedeutet, dass aus drei Bytes der ursprünglichen Zeichenfolge vier Bytes ausgegeben werden. Diese vier Bytes sind Werte des Basis64 -Alphabet -Arrays, wobei jeder Wert ein Byte ist.

Die Ausgabe für das Wort von zwei Zeichen, "It", wird "axq =" von vier Bytes sein, die in Bits als ausgedrückt werden

01100001 01011000 01010001 00111101

Aus dem Array erhalten. Dies bedeutet, dass aus zwei Bytes noch vier Bytes ausgegeben werden.

Die Ausgabe für das Wort eines Zeichens, "i", wird "sq ==" von vier Bytes sein, die in Bits als ausgedrückt werden

01010011 01010001 00111101 00111101

Dies bedeutet, dass aus einem Byte noch vier Bytes ausgegeben werden.

Ein Sextett von 61 (111101) wird als 9 (00111001) ausgegeben. Ein Sextett von = (111101) wird als = (00111101) ausgegeben.

Neue Länge

Hier sind drei Situationen zu berücksichtigen, um eine Schätzung für die neue Länge zu haben.

  • Die ursprüngliche Länge der Zeichenfolge ist ein Vielfalt von 3, e.G., 3, 6, 9, 12, 15 usw. In diesem Fall wird die neue Länge genau 133 betragen.33% der ursprünglichen Länge, weil drei Oktetten als vier Oktetten enden.
  • Die ursprüngliche Länge der Saite ist zwei Bytes lang oder endet mit zwei Bytes nach einem Vielfachen von 3. In diesem Fall wird die neue Länge über 133 liegen.33% der ursprünglichen Länge, da ein Saitenteil von zwei Oktetten als vier Oktetten endet.
  • Die ursprüngliche Länge der Saite ist ein Byte lang oder endet mit einem Byte nach einem Vielfachen von 3. In diesem Fall wird die neue Länge über 133 liegen.33% der ursprünglichen Länge (mehr als im vorherigen Fall), da ein Stringteil eines Oktetts als vier Oktetten endet.

Maximale Länge der Linie

Nach dem Originalzeichenfolge durch das Basis64 -Alphabet -Array und endet mit Oktetten von mindestens 133.33% lang, muss keine Ausgangszeichenfolge mehr als 76 Oktetten lang sein. Wenn eine Ausgangszeichenfolge 76 Zeichen lang ist, muss ein Newline -Zeichen hinzugefügt werden, bevor weitere 76 Oktetten hinzugefügt werden oder weniger Zeichen hinzugefügt werden. Eine lange Ausgabezeichenfolge hat alle Abschnitte, die aus jeweils 76 Zeichen bestehen, mit Ausnahme der letzten, wenn sie nicht bis zu 76 Zeichen sind. Die Leitungsabscheider -Programmierer sind wahrscheinlich das neue Zeilenzeichen '\ n'; Aber es soll "\ r \ n" sein.

Decoding Base64

Um zu dekodieren, machen Sie die Umkehrung der Codierung. Verwenden Sie den folgenden Algorithmus:

  • Wenn die empfangene Zeichenfolge länger als 76 Zeichen (Oktetten) ist, teilen Sie die lange Zeichenfolge in ein Array von Zeichenfolgen auf und entfernen Sie den Zeilenabscheider, der "\ r \ n" oder '\ n "sein kann.
  • Wenn es mehr als eine Zeile von jeweils 76 Zeichen gibt, bedeutet dies alle Zeilen, außer dass die letzten aus Gruppen von jeweils vier Zeichen bestehen. Jede Gruppe führt zu drei Zeichen, die das Basis64 -Alphabet -Array verwenden. Die vier Bytes müssen in sechs Sextets umgewandelt werden, bevor sie in drei Oktetten umgewandelt werden.
  • Die letzte Zeile oder die einzige Zeile, die die Zeichenfolge hatte, besteht immer noch aus Gruppen von vier Zeichen. Die letzte Gruppe von vier Zeichen kann entweder zu einem oder zwei Zeichen führen. Um zu wissen, ob die letzte Gruppe von vier Zeichen zu einem Zeichen führt, prüfen Sie, ob die letzten beiden Oktetten der Gruppe jeweils ASCII sind, =. Wenn die Gruppe zu zwei Zeichen führt, sollte nur der letzte Oktett ASCII sein, =. Jede Vierfachsequenz von Zeichen vor dieser letzten Vierfachsequenz wird wie im vorherigen Schritt behandelt.

Übertragungsfehler

Am empfangenden Ende gibt ein anderes Zeichen als das Zeichen des Zeilentrennungszeichens oder der Zeichen, die kein Wert des Basis64 -Alphabet -Arrays sind, einen Übertragungsfehler an. und sollte gehandhabt werden. In diesem Artikel wird keine Übertragungsfehler behandelt. Hinweis: Das Vorhandensein des Byte = unter den 76 Zeichen ist kein Übertragungsfehler.

C ++ - Bitfunktionen

Grundlegende Mitglieder des Strukturelements können eine Reihe anderer Bits als 8 verabreicht werden. Das folgende Programm zeigt dies:

#enthalten
Verwenden von Namespace STD;
Struktur S3
nicht signiert int a: 6;
nicht signiert int b: 6;
nicht signiert int c: 6;
nicht signiert int d: 6;
S3;
int main ()

S3.a = 25;
S3.B = 6;
S3.C = 61;
S3.D = 39;
Cout<Rückkehr 0;

Die Ausgabe ist:

25, 6, 61, 39

Die Ausgangszahlen sind wie zugewiesen. Jeder nimmt jedoch 6 Bit im Speicher und nicht 8 oder 32 Bit ein. Beachten Sie, wie die Anzahl der Bits in der Erklärung mit dem Dickdarm zugewiesen wird.

Erste 6 Bit aus Oktett extrahieren

C ++ verfügt nicht über eine Funktion oder einen Operator, um den ersten Satz von Bits aus einem Oktett zu extrahieren. Um die ersten 6 Bit zu extrahieren, verändern Sie den Inhalt des Oktetts mit 2 Stellen rechts rechter. Die freien zwei Bits am linken Ende sind mit Nullen gefüllt. Das resultierende Oktett, das ein nicht signiertes Zeichen sein sollte, ist jetzt eine Ganzzahl, die durch die ersten 6 Bit des Oktetts dargestellt wird. Zuweisen Sie dann das resultierende Oktett einem Strukturbitfeldelement von 6 Bits. Der richtige Schichtoperator ist >>, nicht mit dem Extraktionsoperator des Cout -Objekts zu verwechseln.

Angenommen, das Struktur 6-Bit-Feld-Mitglied ist S3.A, dann werden die ersten 6 Bit des Charakters 'D' wie folgt extrahiert:

nicht signiertes char ch1 = 'd';
CH1 = CH1 >> 2;
S3.a = ch1;

Der Wert von S3.A kann jetzt zur Indizierung des Basis64 -Alphabet -Arrays verwendet werden.

Erzeugen Sie das zweite Sextett aus 3 Zeichen

Die zweiten sechs Bit bestehen aus den letzten zwei Bits des ersten Oktetts und den nächsten 4 Bit des zweiten Oktetts. Die Idee ist, die letzten zwei Teile in die fünfte und sechste Position ihres Oktetts zu bringen und den Rest der Teile des Oktets Null zu machen. dann bitweise und es mit den ersten vier Teilen des zweiten Oktets, der bis zu seinem Ende rechts verschoben wurde.

Die letzten zwei Bits in die fünfte und sechste Positionen werden vom Bit-Wise-Linkschichtbetreiber durchgeführt, <<, 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:

nicht signiertes Zeichen i = 'D';
i = i <<4;

Zu diesem Zeitpunkt wurden die freien Bits mit Nullen gefüllt, während die nicht erforderlichen nicht erzielten verschobenen Bits noch vorhanden sind. Um den Rest der Bits in I Zero zu machen, muss ich bitweise und mit 00110000 sein, was die Ganzzahl 96 ist, 96. Die folgende Aussage macht es:

i = i & 96;

Das folgende Codesegment verschiebt die ersten vier Bits des zweiten Oktetts auf die letzten vier Bitpositionen:

nicht signiertes char j = 'o';
J = J >> 4;

Die freien Bits wurden mit Nullen gefüllt. Zu diesem Zeitpunkt habe ich 8 Bit und J hat 8 Bit. Alle 1 in diesen beiden nicht signierten Zeichen sind jetzt in ihren richtigen Positionen. Um das Zeichen für das zweite Sextett zu bekommen, müssen diese beiden 8-Bit-Zeichen bitvoll sein und wie folgt:

nicht signiertes char ch2 = i & j;

CH2 hat noch 8 Bit. Um es sechs Teile zu machen, muss es einem Strukturbitfeldelement von 6 Bit zugeordnet werden. Wenn das Strukturbitfeldelement S3 ist.B, dann erfolgt die Aufgabe wie folgt:

S3.B = CH2;

Fortan S3.B wird anstelle von CH2 verwendet, um das Basis64 -Alphabet -Array zu indizieren.

Hinzufügen von zwei Nullen für das dritte Sextett

Wenn die zu codierte Sequenz zwei Zeichen hat, muss das dritte Sextett zwei Nullen hinzugefügt werden. Angenommen, ein Oktett ist bereits durch zwei Nullbits vorangestellt, und die nächsten vier Bits sind die rechten Bit. Um die letzten beiden Teile dieses Oktetts, zwei Nullen, bitwise und des Oktetts mit 11111100, der Ganzzahl, 252 zu machen, 252. Die folgende Aussage macht es:

nicht signiertes char ch3 = Oktett & 252;

CH3 hat jetzt alle sechs Teile, die die erforderlichen Teile sind, obwohl es immer noch aus 8 Bit besteht. Um es sechs Teile zu machen, muss es einem Strukturbitfeldelement von 6 Bit zugeordnet werden. Wenn das Strukturbitfeldelement S3 ist.c, dann erfolgt die Aufgabe wie folgt:

S3.C = CH3;

Fortan S3.C wird anstelle von CH2 verwendet, um das Basis64 -Alphabet -Array zu indizieren.

Der Rest des Bit -Handlings kann wie in diesem Abschnitt erläutert werden.

Base64 Alphabet Array

Für die Codierung sollte das Array so etwas wie sein,

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

Dekodierung ist der umgekehrte Prozess. Für diese Struktur sollte also eine ungeordnete Karte verwendet werden, so etwas wie,

Under Ordered_map Umap = 'a', 0, 'b', 1, 'c', 2, - - - '/', 63;

Die String -Klasse

Die String-Klasse sollte für die gesamten nicht codierten und codierten Sequenzen verwendet werden. Der Rest der Programmierung ist eine normale C ++ - Programmierung.

Abschluss

Base64 ist ein Zeichensatz von 64 Zeichen, wobei jedes Zeichen aus 6 Bit besteht. Für die Codierung wird jeder Drei-Byte der ursprünglichen Zeichenfolge in vier Sextetten mit jeweils 6 Bits umgewandelt. Diese Sextets werden als Indizes für die Base64 -Alphabet -Tabelle für die Codierung verwendet. Wenn die Sequenz aus zwei Zeichen besteht, werden noch vier Sextets erhalten, wobei das letzte Sextett die Nummer 61 ist. Wenn die Sequenz aus einem Zeichen besteht, werden noch vier Sextets erhalten, wobei die letzten beiden Sextets zwei der Nummer 61 sind.

Dekodierung macht das Gegenteil.