Los datos en la computadora se almacenan en bytes de 8 bits cada uno. Los datos se envían fuera de la computadora en bytes de 8 bits cada uno. Los datos se reciben en la computadora en bytes de 8 bits cada uno.
Se puede convertir una corriente de bytes en una corriente de sextets (6 bits por símbolo). Y esa es la codificación base64. Se puede convertir una corriente de sextets en una corriente de bytes. Y esa es la decodificación base64. En otras palabras, una corriente de caracteres ASCII se puede convertir en una corriente de símbolos de sexteto. Esto es codificación, y lo contrario se está decodificando. La corriente de símbolos de sexteto, convertido de una corriente de símbolos de octeto (byte), es más larga que la corriente de símbolos de octeto por número. En otras palabras, una corriente de caracteres base64 es más larga que la corriente correspondiente de caracteres ASCII. Bueno, codificar en base64 y decodificar de él no es tan sencillo como se simplemente expresado.
Este artículo explica la codificación y decodificación de Base64 con el lenguaje informático C ++. La primera parte del artículo explica la codificación y decodificación de Base64 correctamente. La segunda parte muestra cómo algunas características de C ++ se pueden usar para codificar y decodificar base64. En este artículo, la palabra "octeto" y "byte" se usan indistintamente.
Contenido del artículo
Avanzando hasta la base 64
Se puede representar un alfabeto o un conjunto de caracteres de 2 símbolos con un bit por símbolo. Deje que los símbolos del alfabeto consistan en: cero y uno. En este caso, cero es bit 0 y uno es bit 1.
Un alfabeto o conjunto de caracteres de 4 símbolos se puede representar con dos bits por símbolo. Deje que los símbolos del alfabeto consistan en: 0, 1, 2, 3. En esta situación, 0 es 00, 1 es 01, 2 es 10 y 3 son 11.
Se puede representar un alfabeto de 8 símbolos con tres bits por símbolo. Deje que los símbolos del alfabeto consistan en: 0, 1, 2, 3, 4, 5, 6, 7. En esta situación, 0 es 000, 1 es 001, 2 es 010, 3 es 011, 4 es 100, 5 es 101, 6 es 110 y 7 es 111.
Un alfabeto de 16 símbolos se puede representar con cuatro bits por símbolo. Deje que los símbolos del alfabeto consistan en: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. En esta situación, 0 es 0000, 1 es 0001, 2 es 0010, 3 es 0011, 4 es 0100, 5 es 0101, 6 es 0110, 7 es 0111, 8 es 1000, 9 es 1001, A es 1010, b IS es 1011, C es 1100, D es 1101, E es 1110 y F es 1111.
Un alfabeto de 32 símbolos diferentes se puede representar con cinco bits por símbolo.
Esto nos lleva a un alfabeto de 64 símbolos diferentes. Un alfabeto de 64 símbolos diferentes se puede representar con seis bits por símbolo. Hay un conjunto de caracteres particular de 64 símbolos diferentes, llamados Base64. En este conjunto, los primeros 26 símbolos son las 26 letras mayúsculas del idioma hablado en inglés, en su orden. Estos 26 símbolos son los primeros números binarios de 0 a 25, donde cada símbolo es un sexteto, seis bits. Los siguientes números binarios de 26 a 51 son las 26 letras minúsculas del idioma hablado inglés, en su orden; De nuevo, cada símbolo, un sexteto. Los siguientes números binarios de 52 a 61 son los 10 dígitos árabes, en su orden; Aún así, cada símbolo, un sexteto.
El número binario para 62 es para el símbolo +, y el número binario para 63 es para el símbolo / . Base64 tiene diferentes variantes. Entonces, algunas variantes tienen diferentes símbolos para los números binarios de 62 y 63.
La tabla Base64, que muestra correspondencias para el índice, el número binario y el carácter, es:
El alfabeto base64
Índice | Binario | Carbonizarse | Índice | Binario | Carbonizarse | Índice | Binario | Carbonizarse | Índice | Binario | Carbonizarse |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 000000 | A | dieciséis | 010000 | Q | 32 | 100000 | gramo | 48 | 110000 | w |
1 | 000001 | B | 17 | 010001 | Riñonal | 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 | GRAMO | 22 | 010110 | W | 38 | 100110 | metro | 54 | 110110 | 2 |
7 | 000111 | H | 23 | 010111 | X | 39 | 100111 | norte | 55 | 110111 | 3 |
8 | 001000 | I | 24 | 011000 | Y | 40 | 101000 | O | 56 | 111000 | 4 |
9 | 001001 | J | 25 | 011001 | Z | 41 | 101001 | pag | 57 | 111001 | 5 |
10 | 001010 | K | 26 | 011010 | a | 42 | 101010 | Q | 58 | 111010 | 6 |
11 | 001011 | L | 27 | 011011 | b | 43 | 101011 | riñonal | 59 | 111011 | 7 |
12 | 001100 | METRO | 28 | 011100 | C | 44 | 101100 | s | 60 | 111100 | 8 |
13 | 001101 | norte | 29 | 011101 | d | 45 | 101101 | T | 61 | 111101 | 9 |
14 | 001110 | O | 30 | 011110 | mi | 46 | 101110 | u | 62 | 111110 | + |
15 | 001111 | PAG | 31 | 011111 | F | 47 | 101111 | V | 63 | 111111 | / |
Relleno =
En realidad hay 65 símbolos. El último símbolo es =, cuyo número binario todavía consta de 6 bits, que es 111101. No entra en conflicto con el símbolo base64 de 9 - ver más abajo.
Base de codificación64
Sextet campos de bits
Considere la palabra:
perro
Hay tres bytes ascii para esta palabra, que son:
01100100 01101111 01100111
unido. Estos son 3 octetos, pero consta de 4 sextets de la siguiente manera:
011001 000110 111101 100111
De la tabla de alfabeto base64 arriba, estos 4 sextets son los símbolos,
ZG9N
Observe que la codificación de "perro" en Base64 es "ZG9N", que no es comprensible.
Base64 codifica una secuencia de 3 octetos (bytes) en una secuencia de 4 sextets. 3 octetos o 4 sextets son 24 bits.
Considere ahora la siguiente palabra:
él
Hay dos octetos ASCII para esta palabra, que son:
01101001 01110100
unido. Estos son 2 octetos pero consta de 2 sextets y 4 bits. Un flujo de caracteres Base64 está formado por sextets (6 bits por personaje). Por lo tanto, se deben agregar dos bits cero a estos 16 bits para tener 3 sextets, es decir:
011010 010111 010000
Eso no es todo. La secuencia Base64 está compuesta por 4 sextets por grupo; es decir, 24 bits por grupo. El personaje de relleno = es 111101. Ya se han agregado dos bits cero a los 16 bits para tener 18 bits. Entonces, si los 6 bits de relleno del personaje de relleno se agregan a los 18 bits, habrá 24 bits según sea necesario. Eso es:
011010 010111 010000 111101
Los últimos seis bits del último sexteto es el sexteto de relleno, = . Estos 24 bits consisten en 4 sextets, de los cuales el sexteto de último pero uno tiene los primeros 4 bits del símbolo base64, seguido de dos bits cero.
Ahora, considere la siguiente palabra de un personaje:
I
Hay un octeto ASCII para esta palabra, que es:
01001001
Esto es 1 octeto pero consta de 1 sexteto y 2 bits. Un flujo de caracteres Base64 está formado por sextets (6 bits por personaje). Por lo tanto, se deben agregar cuatro bits cero a estos 8 bits para tener 2 sextets, es decir:
010010 010000
Eso no es todo. La secuencia Base64 está compuesta por 4 sextets por grupo; es decir, 24 bits por grupo. El personaje de relleno = es 111101, que tiene seis bits de largo. Ya se han agregado cuatro bits cero a los 8 bits para tener 12 bits. Esto no es hasta cuatro sextets. Entonces, se deben agregar dos sextets más de relleno para hacer 4 sextets, es decir:
010010 010000 111101 111101
Flujo de salida de base64
En el programa, se debe hacer una matriz de Chars del alfabeto Base64, donde el índice 0 tiene el carácter de 8 bits, a; El índice 1 tiene el carácter de 8 bits, b; El índice 2 tiene el carácter de 8 bits, c, hasta que el índice 63 tiene el carácter de 8 bits, / .
Entonces, la salida para la palabra de tres caracteres, "perro" será "zg9n" de cuatro bytes, expresado en bits como
01011010 01000111 00111001 01101110
donde z es 01011010 de 8 bits; G es 01000111 de 8 bits; 9 es 00111001 de 8 bits, y n es 01101110 de 8 bits. Esto significa que a partir de tres bytes de la cadena original, se emiten cuatro bytes. Estos cuatro bytes son valores de la matriz de alfabeto base64, donde cada valor es un byte.
La salida para la palabra de dos caracteres, "it" será "axq =" de cuatro bytes, expresado en bits como
01100001 01011000 01010001 00111101
obtenido de la matriz. Esto significa que a partir de dos bytes, cuatro bytes todavía se producen.
La salida para la palabra de un personaje, "i" será "sq ==" de cuatro bytes, expresado en bits como
01010011 01010001 00111101 00111101
Esto significa que a partir de un byte, cuatro bytes todavía se producen.
Se emite un sexteto de 61 (111101) como 9 (00111001). Se emite un sexteto de = (111101) como = (00111101).
Nuevo longitud
Hay tres situaciones a considerar aquí para tener una estimación de la nueva longitud.
Longitud máxima de la línea
Después de pasar de la cadena original a través de la matriz de alfabeto base64 y terminar con octetos de al menos 133.33% largo, ninguna cadena de salida debe tener más de 76 octetos de largo. Cuando una cadena de salida tiene 76 caracteres, se debe agregar un carácter de nueva línea antes de otros 76 octetos, o se agregan menos caracteres. Una cadena de salida larga tiene todas las secciones, que constan de 76 caracteres cada una, excepto la última, si no es de hasta 76 caracteres. El uso de los programadores de separadores de línea es probablemente el carácter de Newline, '\ n'; Pero se supone que es "\ r \ n".
Base de decodificación64
Para decodificar, hacer el reverso de la codificación. Use el siguiente algoritmo:
Error de transmisión
En el extremo receptor, cualquier carácter que no sea el del carácter de separación de línea o los caracteres que no es un valor de la matriz de alfabeto Base64 indica un error de transmisión; y debe ser manejado. El manejo de errores de transmisión no se aborda en este artículo. Nota: La presencia del byte, = entre los 76 caracteres, no es un error de transmisión.
Características de bit c ++
A los miembros fundamentales del elemento estructural se les puede dar una serie de bits que no sean 8. El siguiente programa ilustra esto:
#incluir
usando el espacio de nombres STD;
struct s3
sin firmar 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<regresar 0;
La salida es:
25, 6, 61, 39
Los enteros de salida son asignados. Sin embargo, cada uno ocupa 6 bits en la memoria y no 8 o 32 bits. Observe cómo se asigna el número de bits, en la declaración, con el colon.
Extraer los primeros 6 bits del octeto
C ++ no tiene una función u operador para extraer el primer conjunto de bits de un octeto. Para extraer los primeros 6 bits, desplaza a la derecha el contenido del octeto por 2 lugares. Los dos bits desocupados en el extremo izquierdo están llenos de ceros. El octeto resultante, que debería ser un carbón sin firmar, ahora es un entero, representado por los primeros 6 bits del octeto. Luego asigne el octeto resultante a un miembro de campo de bits struct de 6 bits. El operador de cambio correcto es >>, que no debe confundirse con el operador de extracción del objeto Cout.
Suponiendo que el miembro del campo de bits struct 6 es, S3.A, luego los primeros 6 bits del personaje 'D' se extraen de la siguiente manera:
unsigned char ch1 = 'd';
CH1 = CH1 >> 2;
s3.a = ch1;
El valor de S3.ahora se puede usar para indexar la matriz de alfabeto base64.
Producir el segundo sexteto de 3 caracteres
Los segundos seis bits consisten en los últimos dos bits del primer octeto y los siguientes 4 bits del segundo octeto. La idea es obtener los dos últimos bits en las posiciones quinta y sexta de su octeto y hacer que el resto de los bits del octeto cero; Luego, en cuanto a bits y con los primeros cuatro bits del segundo octeto que se ha desplazado a la derecha hasta su fin.
El cambio de izquierda los dos últimos bits a las posiciones quinta y sexta es realizada por el operador de cambio de izquierda de bits, <<, 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:
unsigned char i = 'd';
i = i <<4;
En este punto, los bits desocupados se han llenado de ceros, mientras que los bits desplegados no se requieren que no se requieran. Para hacer el resto de los bits en i cero, tengo que estar bits y con 00110000, que es el entero, 96. La siguiente declaración lo hace:
i = i y 96;
El siguiente segmento de código, cambia los primeros cuatro bits del segundo octeto a las últimas cuatro posiciones de bits:
unsigned char j = 'o';
j = j >> 4;
Los bits desocupados han sido llenos de ceros. En este punto, tengo 8 bits y J tiene 8 bits. Todos los 1 en estos dos caracteres sin firmar están ahora en sus posiciones correctas. Para obtener el char, para el segundo sexteto, estos dos caracteres de 8 bits deben ser bits y, de la siguiente manera:
unsigned char ch2 = i & j;
CH2 todavía tiene 8 bits. Para que sea seis bits, debe asignarse a un miembro de campo de bits de struct de 6 bits. Si el miembro del campo de bits struct es S3.B, entonces la tarea se realizará de la siguiente manera:
s3.b = CH2;
En adelante, S3.B se usará en lugar de CH2 para indexar la matriz de alfabeto base64.
Agregar dos ceros para el tercer sexteto
Cuando la secuencia que se codificará tiene dos caracteres, el tercer sexteto debe agregarse dos ceros. Suponga que un octeto ya está prefijado por dos bits cero, y los siguientes cuatro bits son los bits correctos. Para hacer los dos últimos bits de este octeto, dos ceros, bits y el octeto con 11111100, que es el entero, 252. La siguiente declaración lo hace:
Char sin firmar CH3 = octeto y 252;
CH3 ahora tiene los últimos seis bits, que son los bits requeridos, aunque todavía consta de 8 bits. Para que sea seis bits, debe asignarse a un miembro de campo de bits de struct de 6 bits. Si el miembro del campo de bits struct es S3.C, entonces la tarea se realizará de la siguiente manera:
s3.c = CH3;
En adelante, S3.C se usará en lugar de CH2 para indexar la matriz de alfabeto base64.
El resto del manejo de bits se puede hacer como se explica en esta sección.
Matriz de alfabeto base64
Para la codificación, la matriz debería ser algo como,
unsigned char arr [] = 'a', 'b', 'c', - - - '/';
La decodificación es el proceso inverso. Entonces, se debe utilizar un mapa desordenado para esta estructura, algo como,
desordenable_mapumap = 'a', 0, 'b', 1, 'c', 2, - - - '/', 63;
La clase de cadena
La clase de cadena debe usarse para las secuencias totales no codificadas y codificadas. El resto de la programación es una programación normal de C ++.
Conclusión
Base64 es un conjunto de caracteres de 64 caracteres, donde cada personaje consta de 6 bits. Para la codificación, cada tres bytes de la cadena original se convierte en cuatro sextets de 6 bits cada uno. Estos sextets se utilizan como índices para la tabla de alfabeto base64 para codificar. Si la secuencia consta de dos caracteres, todavía se obtienen cuatro sextets, con el último sexteto, siendo el número 61. Si la secuencia consta de un personaje, todavía se obtienen cuatro sextets, con los dos últimos sextetas, siendo dos del número 61.
La decodificación hace el reverso.