Base 64 es un esquema de codificación que convierte datos binarios a formato de texto para que los datos de texto codificados puedan transportarse fácilmente a través de una red sin corrupción y sin pérdida de datos. Base64 se usa comúnmente en varias aplicaciones, incluido el correo electrónico a través de MIME y el almacenamiento de datos complejos en XML.
El problema de enviar datos binarios normales a una red es que los protocolos subyacentes pueden malinterpretar los bits, produciendo datos incorrectos en el nodo receptor y por eso usamos este código.
¿Por qué base 64?
Esos caracteres están ampliamente presentes en muchos conjuntos de caracteres en el texto resultante después de codificar nuestros datos y, por lo tanto, es menos probable que corrompan o modifiquen los datos.
¿Cómo convertir al formato base 64?
El conjunto de caracteres está en base64.
char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz0123456789+/" // 64 characters
Idea básica
Tomemos un ejemplo. Necesitamos codificar la cadena «MENON» en formato base64. Llamamos «MENON» porque input_strpor encima del conjunto de caracteres base64 («ABC..+/») como char_series y la cadena codificada resultante como re_str.
- Toma 3 personajes de input_str es decir, «MAN» ya que cada carácter es de 8 bits tendremos (8 * 3) 24 bits.
- Agruparlos en bloques de 6 bits cada uno (24/6 = 4 bloques). (¿Por qué 6?) Como 2^6 = 64 caracteres, con 6 bits podemos representar cada carácter en char_series.
- Convierta cada bloque de 6 bits a su valor decimal correspondiente. El valor decimal resultante es el índice del carácter codificado resultante i char_series.
- Así que por cada 3 caracteres de input_str tenemos 4 caracteres i re_str.
- ¿Qué pasa si tenemos menos de 3 caracteres? input_str izquierda, es decir. «EN». Tenemos 16 bits y habrá 16/6 bloques = 2 bloques. La mayoría de los 4 bits no harán un bloque correcto (1 bloque = 6 bits), por lo que agregaremos ceros al lado derecho del bloque para que sea un bloque correcto, es decir, se agregarán 2 ceros al lado derecho. Ahora que tenemos 3 bloques correctos, encuentre el valor decimal correspondiente de cada bloque para obtener un índice.
- Como había menos de 3 caracteres («AR») i input_str agregaremos «=» en res_str. ej., “ON” aquí 3 – 2 = pad 1 de “=” en re_str.
Un ejemplo
1. Convierta “MENON” en formato de estado binario (8 bits). Tome cada carácter de la cadena y escriba su representación binaria de 8 bits.
Los valores ASCII de los caracteres de una cadena a codificar
M : 77 (01001101), E : 69 (01000101), N : 78 (01001110), O : 79 (01001111), N : 78 (01001110)
Los datos binarios resultantes de la cadena anterior son:
01001101 01000101 01001110 01001111 01001110
2. Comenzando desde el lado izquierdo, haz bloques de él. 6 poco a poco hasta cubrir todos los bits
Flujo de bits:
(010011) (010100) (010101) (001110) (010011) (110100) (1110)
3. Si el bloque más a la derecha tiene menos de 6 bits, simplemente agregue ceros al lado derecho de ese bloque para que sea de 6 bits. Aquí, en el ejemplo anterior, necesitamos agregar 2 ceros para hacer 6.
Flujo de bits:
(010011) (010100) (010101) (001110) (010011) (110100) (111000)
Tenga en cuenta los ceros en negrita.
4. Tome 3 caracteres de input_str («MEN»), es decir, 24 bits, y obtenga el valor decimal correspondiente (índice para char_set).
BLOQUES :
INDEX --> (010011) : 19, (010100) : 20, (010101) : 21, (001110) : 14 char_set[19] = T, char_set[20] = U, char_set[21] = V, char_set[14] = O
Por lo tanto, nuestro input_str = «MAN» se convertirá en una cadena codificada «TUVO».
5. Tome los caracteres restantes («AR»). Necesitamos anclar la cadena codificada resultante con 1 «=» porque la cantidad de caracteres es inferior a 3 en input_str. (3 – 2 = almohadilla 1)
BLOQUES :
INDEX --> (010011) : 19 (110100) : 52 (111000) : 56 char_set[19] = T char_set[52] = 0 char_set[56] = 4 So our input_str = "ON" will be converted to encoded string "T04=".
Ejemplos:
Input : MENON // string in ASCII Output :TUVOT04= // encoded string in Base 64. Input : geeksforgeeks Output : Z2Vla3Nmb3JnZWVrcw==
Podemos usar operadores bit a bit para codificar nuestra cadena. Podemos tomar un entero «val» (generalmente 4 bytes en la mayoría de los compiladores) y almacenar cada carácter de input_str (3 a la vez) en val. Los caracteres de input_str se almacenarán en val
en forma de bits. Usaremos (operador OR) para almacenar los caracteres y (LEFT – SHIFT) por 8 para que
para hacer espacio para otros 8 bits. De manera similar, usaremos (DERECHA – MAYÚS) para recuperar bits de val 6 a la vez
y obtenga un poco de valor haciendo & con 63 (111111) que nos dará un índice. Entonces podemos obtener nuestro carácter resultante yendo a ese índice char_set.
C++
// C++ program to encode an ASCII // string in Base64 format #include <iostream> using namespace std; #define SIZE 1000 // Takes string to be encoded as input // and its length and returns encoded string char * base64Encoder( char input_str[], int len_str) { // Character set of base64 encoding scheme char char_set[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; // Resultant string char *res_str = ( char *) malloc (SIZE * sizeof ( char )); int index, no_of_bits = 0, padding = 0, val = 0, count = 0, temp; int i, j, k = 0; // Loop takes 3 characters at a time from // input_str and stores it in val for (i = 0; i < len_str; i += 3) { val = 0, count = 0, no_of_bits = 0; for (j = i; j < len_str && j <= i + 2; j++) { // binary data of input_str is stored in val val = val << 8; // (A + 0 = A) stores character in val val = val | input_str[j]; // calculates how many time loop // ran if "MEN" -> 3 otherwise "ON" -> 2 count++; } no_of_bits = count * 8; // calculates how many "=" to append after res_str. padding = no_of_bits % 3; // extracts all bits from val (6 at a time) // and find the value of each block while (no_of_bits != 0) { // retrieve the value of each block if (no_of_bits >= 6) { temp = no_of_bits - 6; // binary of 63 is (111111) f index = (val >> temp) & 63; no_of_bits -= 6; } else { temp = 6 - no_of_bits; // append zeros to right if bits are less than 6 index = (val << temp) & 63; no_of_bits = 0; } res_str[k++] = char_set[index]; } } // padding is done here for (i = 1; i <= padding; i++) { res_str[k++] = '=' ; } res_str[k] = ' ' ; return res_str; } // Driver code int main() { char input_str[] = "MENON" ; int len_str; // calculates length of string len_str = sizeof (input_str) / sizeof (input_str[0]); // to exclude ' ' character len_str -= 1; cout << "Input string is : " << input_str << endl; cout << "Encoded string is : " << base64Encoder(input_str, len_str)<< endl; return 0; } // This code is contributed by shivanisinghss2110 |
C
// C program to encode an ASCII // string in Base64 format #include <stdio.h> #include <stdlib.h> #define SIZE 1000 // Takes string to be encoded as input // and its length and returns encoded string char * base64Encoder( char input_str[], int len_str) { // Character set of base64 encoding scheme char char_set[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; // Resultant string char *res_str = ( char *) malloc (SIZE * sizeof ( char )); int index, no_of_bits = 0, padding = 0, val = 0, count = 0, temp; int i, j, k = 0; // Loop takes 3 characters at a time from // input_str and stores it in val for (i = 0; i < len_str; i += 3) { val = 0, count = 0, no_of_bits = 0; for (j = i; j < len_str && j <= i + 2; j++) { // binary data of input_str is stored in val val = val << 8; // (A + 0 = A) stores character in val val = val | input_str[j]; // calculates how many time loop // ran if "MEN" -> 3 otherwise "ON" -> 2 count++; } no_of_bits = count * 8; // calculates how many "=" to append after res_str. padding = no_of_bits % 3; // extracts all bits from val (6 at a time) // and find the value of each block while (no_of_bits != 0) { // retrieve the value of each block if (no_of_bits >= 6) { temp = no_of_bits - 6; // binary of 63 is (111111) f index = (val >> temp) & 63; no_of_bits -= 6; } else { temp = 6 - no_of_bits; // append zeros to right if bits are less than 6 index = (val << temp) & 63; no_of_bits = 0; } res_str[k++] = char_set[index]; } } // padding is done here for (i = 1; i <= padding; i++) { res_str[k++] = '=' ; } res_str[k] = ' ;' ; return res_str; } // Driver code int main() { char input_str[] = "MENON" ; int len_str; // calculates length of string len_str = sizeof (input_str) / sizeof (input_str[0]); // to exclude ' ' character len_str -= 1; printf ( "Input string is : %sn" , input_str); printf ( "Encoded string is : %sn" , base64Encoder(input_str, len_str)); return 0; } |
Input string is : MENON Encoded string is : TUVOT04=
Complejidad del tiempo: O(2 * N) poner bits en val + recuperar bits en val
Complejidad espacial: O(N) donde N es el tamaño de la cadena de entrada
Práctica: Implementar un decodificador base 64
Este artículo ha sido agregado Arshpreet Soodan. Si te gusta GeeksforGeeks y quieres contribuir, también puedes escribir un artículo usándolo. escribir.geeksforgeeks.org o envíe su artículo por correo a review-team@geeksforgeeks.org. Vea su artículo destacado en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba un comentario si encuentra algún problema o si desea compartir más información sobre el tema tratado anteriormente.