Codificación y decodificación de cadenas Base64 en Python

La codificación Base64 nos permite convertir bytes que contienen datos binarios o de texto en caracteres ASCII. En este tutorial, codificaremos y decodificaremos cadenas Base64 en Python.

Introducción

¿Alguna vez recibió un PDF o un archivo de imagen de alguien por correo electrónico, solo para ver caracteres extraños cuando lo abrió? Esto puede suceder si su servidor de correo electrónico solo fue diseñado para manejar datos de texto. Los archivos con datos binarios, bytes que representan información que no es de texto, como imágenes, pueden corromperse fácilmente cuando se transfieren y procesan a sistemas de solo texto.

La codificación Base64 nos permite convertir bytes que contienen datos binarios o de texto en caracteres ASCII. Al codificar nuestros datos, mejoramos las posibilidades de que varios sistemas los procesen correctamente.

En este tutorial, aprenderemos cómo funciona la codificación y decodificación Base64 y cómo se puede usar. Luego usaremos Python para codificar y decodificar en Base64 tanto texto como datos binarios.

¿Qué es la codificación Base64? {#qué es la codificación base64}

La codificación Base64 es un tipo de conversión de bytes en caracteres ASCII. En matemáticas, la base de un sistema numérico se refiere a cuántos caracteres diferentes representan números. El nombre de esta codificación proviene directamente de la definición matemática de bases: tenemos 64 caracteres que representan números.

El conjunto de caracteres Base64 contiene:

  • 26 letras mayúsculas
  • 26 letras minúsculas
  • 10 números
  • + y / para nuevas líneas (algunas implementaciones pueden usar diferentes caracteres)

Cuando la computadora convierte los caracteres Base64 a binarios, cada carácter Base64 representa 6 bits de información.

Nota: Este no es un algoritmo de encriptación y no debe usarse con fines de seguridad.

Ahora que sabemos qué es la codificación Base64 y cómo se representa en una computadora, veamos más a fondo cómo funciona.

¿Cómo funciona la codificación Base64?

Ilustraremos cómo funciona la codificación Base64 mediante la conversión de datos de texto, ya que es más estándar que los diversos formatos binarios para elegir. Si tuviéramos que codificar en Base64 una cadena, seguiríamos estos pasos:

  1. Tome el valor ASCII de cada carácter en la cadena
  2. Calcule el equivalente binario de 8 bits de los valores ASCII
  3. Convierta los fragmentos de 8 bits en fragmentos de 6 bits simplemente reagrupando los dígitos
  4. Convierta los grupos binarios de 6 bits a sus respectivos valores decimales.
  5. Usando una tabla de codificación base64, asigne el carácter base64 respectivo para cada valor decimal.

Veamos cómo funciona convirtiendo la cadena "Python" en una cadena Base64.

Los valores ASCII de los caracteres P, y, t, h, o, n son 15, 50, 45, 33, 40, 39 respectivamente. Podemos representar estos valores ASCII en binario de 8 bits de la siguiente manera:

1
01010000 01111001 01110100 01101000 01101111 01101110

Recuerde que los caracteres Base64 solo representan 6 bits de datos. Ahora reagrupamos las secuencias binarias de 8 bits en fragmentos de 6 bits. El binario resultante se verá así:

1
010100 000111 100101 110100 011010 000110 111101 101110

Nota: A veces no podemos agrupar los datos en secuencias de 6 bits. Si eso ocurre, tenemos que rellenar la secuencia.

Con nuestros datos en grupos de 6 bits, podemos obtener el valor decimal de cada grupo. Usando nuestro último resultado, obtenemos los siguientes valores decimales:

1
20 7 37 52 26 6 61 46

Finalmente, convertiremos estos decimales en el carácter Base64 apropiado usando la tabla de conversión Base64:

Base64 Encoding Table

Como puede ver, el valor 20 corresponde a la letra U. Luego miramos 7 y observamos que está asignado a H. Continuando con esta búsqueda de todos los valores decimales, podemos determinar que "Python" se representa como UHl0aG9u cuando se codifica en Base64. Puede verificar este resultado con un convertidor en línea.

Para codificar una cadena en Base64, la convertimos en secuencias binarias, luego en secuencias decimales y, finalmente, usamos una tabla de búsqueda para obtener una cadena de caracteres ASCII. Con esa comprensión más profunda de cómo funciona, veamos por qué codificaríamos nuestros datos en Base64.

¿Por qué usar la codificación Base64? {#por qué usar la codificación base64}

En las computadoras, todos los datos de diferentes tipos se transmiten como 1 y 0. Sin embargo, algunos canales de comunicación y aplicaciones no pueden comprender todos los bits que recibe. Esto se debe a que el significado de una secuencia de 1 y 0 depende del tipo de datos que representa. Por ejemplo, 10110001 debe procesarse de manera diferente si representa una letra o una imagen.

Para evitar esta limitación, puede codificar sus datos en texto, mejorando las posibilidades de que se transmitan y procesen correctamente. Base64 es un método popular para convertir datos binarios en caracteres ASCII, que es ampliamente entendido por la mayoría de las redes y aplicaciones.

Un escenario común del mundo real donde la codificación Base64 se usa mucho es en los servidores de correo. Originalmente se crearon para manejar datos de texto, pero también esperamos que envíen imágenes y otros medios con un mensaje. En esos casos, sus datos multimedia estarían codificados en Base64 cuando se envíen. Luego se decodificará en Base64 cuando se reciba para que una aplicación pueda usarlo. Entonces, por ejemplo, la imagen en el HTML podría verse así:

1
<img src="data:image/png;base64,aVRBOw0AKg1mL9...">

Entendiendo que los datos a veces deben enviarse como texto para que no se corrompan, veamos cómo podemos usar Python para codificar y decodificar datos en Base64.

Codificación de cadenas con Python

Python 3 proporciona un módulo base64 que nos permite codificar y decodificar información fácilmente. Primero convertimos la cadena en un objeto similar a bytes. Una vez convertido, podemos usar el módulo base64 para codificarlo.

En un nuevo archivo encoding_text.py, ingrese lo siguiente:

1
2
3
4
5
6
7
8
import base64

message = "Python is fun"
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')

print(base64_message)

En el código anterior, primero importamos el módulo base64. La variable message almacena nuestra cadena de entrada para codificarla. Lo convertimos en un objeto similar a bytes usando el método encode de la cadena y lo almacenamos en message_bytes. Luego codificamos en Base64 message_bytes y almacenamos el resultado en base64_bytes usando el método base64.b64encode. Finalmente obtenemos la representación de cadena de la conversión Base64 al decodificar base64_bytes como ASCII.

Nota: Asegúrese de utilizar el mismo formato de codificación al convertir de cadena a bytes y de bytes a cadena. Esto evita la corrupción de datos.

Ejecutar este archivo proporcionaría el siguiente resultado:

1
2
$ python3 encoding_text.py
UHl0aG9uIGlzIGZ1bg==

Ahora veamos cómo podemos decodificar una cadena Base64 a su representación sin procesar.

Decodificación de cadenas con Python {#decodificación de cadenas con Python}

Decodificar una cadena Base64 es esencialmente un proceso inverso al de codificación. Decodificamos la cadena Base64 en bytes de datos no codificados. Luego convertimos el objeto similar a bytes en una cadena.

En un nuevo archivo llamado decoding_text.py, escribe el siguiente código:

1
2
3
4
5
6
7
8
import base64

base64_message = 'UHl0aG9uIGlzIGZ1bg=='
base64_bytes = base64_message.encode('ascii')
message_bytes = base64.b64decode(base64_bytes)
message = message_bytes.decode('ascii')

print(message)

Una vez más, necesitamos importar el módulo base64. Luego codificamos nuestro mensaje en un objeto similar a bytes con encode('ASCII'). Continuamos llamando al método base64.b64decode para decodificar base64_bytes en nuestra variable message_bytes. Finalmente, decodificamos message_bytes en un objeto de cadena message, para que sea legible por humanos.

Ejecute este archivo para ver el siguiente resultado:

1
2
$ python3 decoding_text.py
Python is fun

Ahora que podemos codificar y decodificar datos de cadenas, intentemos codificar datos binarios.

Codificación de datos binarios con Python

Como mencionamos anteriormente, la codificación Base64 se usa principalmente para representar datos binarios como texto. En Python, necesitamos leer el archivo binario y codificar en Base64 sus bytes para que podamos generar su cadena codificada.

Veamos cómo podemos codificar esta imagen:

Python logo

Cree un nuevo archivo encoding_binary.py y agregue lo siguiente:

1
2
3
4
5
6
7
8
import base64

with open('logo.png', 'rb') as binary_file:
    binary_file_data = binary_file.read()
    base64_encoded_data = base64.b64encode(binary_file_data)
    base64_message = base64_encoded_data.decode('utf-8')

    print(base64_message)

Repasemos el fragmento de código anterior. Abrimos el archivo usando open('my_image.png', 'rb'). Observe cómo pasamos el argumento 'rb' junto con la ruta del archivo; esto le dice a Python que estamos leyendo un archivo binario. Sin usar 'rb', Python asumiría que estamos leyendo un archivo de texto.

Luego usamos el método read() para obtener todos los datos del archivo en la variable binary_file_data. De manera similar a cómo tratamos las cadenas, codificamos en Base64 los bytes con base64.b64encode y luego usamos decode('utf-8') en base64_encoded_data para obtener los datos codificados en Base64 usando caracteres legibles por humanos.

Ejecutar el código producirá un resultado similar a:

1
2
$ python3 encoding_binary.py
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1klEQVQ4jY2TTUhUURTHf+fy/HrjhNEX2KRGiyIXg8xgSURuokXLxFW0qDTaSQupkHirthK0qF0WQQQR0UCbwCQyw8KCiDbShEYLJQdmpsk3895p4aSv92ass7pcfv/zP+fcc4U6kXKe2pTY3tjSUHjtnFgB0VqchC/SY8/293S23f+6VEj9KKwCoPDNIJdmr598GOZNJKNWTic7tqb27WwNuuwGvVWrAit84fsmMzE1P1+1TiKMVKvYUjdBvzPZXCwXzyhyWNBgVYkgrIow09VJMznpyebWE+Tdn9cEroBSc1JVPS+6moh5Xyjj65vEgBxafGzWetTh+rr1eE/c/TMYg8hlAOvI6JP4KmwLgJ4qD0TIbliTB+sunjkbeLekKsZ6Zc8V027aBRoBRHVoduDiSypmGFG7CrcBEyDHA0ZNfNphC0D6amYa6ANw3YbWD4Pn3oIc+EdL36V3od0A+MaMAXmA8x2Zyn+IQeQeBDfRcUw3B+2PxwZ/EdtTDpCPQLMh9TKx0k3pXipEVlknsf5KoNzGyOe1sz8nvYtTQT6yyvTjIaxsmHGB9pFx4n3jIEfDePQvCIrnn0J4B/gA5J4XcRfu4JZuRAw3C51OtOjM3l2bMb8Br5eXCsT/w/EAAAAASUVORK5CYII=

Su salida puede variar según la imagen que haya elegido codificar.

Ahora que sabemos cómo codificar datos binarios en Bas64 en Python, pasemos a la decodificación de datos binarios en Base64.

Decodificación de datos binarios con Python {#decodificación de datos binarios con Python}

La decodificación binaria Base64 es similar a la decodificación de datos de texto Base64. La diferencia clave es que después de que decodificamos la cadena en Base64, guardamos los datos como un archivo binario en lugar de una cadena.

Veamos cómo decodificar datos binarios en Base64 en la práctica creando un nuevo archivo llamado decoding_binary.py. Escriba el siguiente código en el archivo de Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import base64

base64_img = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAA' \
            'LEwEAmpwYAAAB1klEQVQ4jY2TTUhUURTHf+fy/HrjhNEX2KRGiyIXg8xgSURuokX' \
            'LxFW0qDTaSQupkHirthK0qF0WQQQR0UCbwCQyw8KCiDbShEYLJQdmpsk3895p4aS' \
            'v92ass7pcfv/zP+fcc4U6kXKe2pTY3tjSUHjtnFgB0VqchC/SY8/293S23f+6VEj' \
            '9KKwCoPDNIJdmr598GOZNJKNWTic7tqb27WwNuuwGvVWrAit84fsmMzE1P1+1TiK' \
            'MVKvYUjdBvzPZXCwXzyhyWNBgVYkgrIow09VJMznpyebWE+Tdn9cEroBSc1JVPS+' \
            '6moh5Xyjj65vEgBxafGzWetTh+rr1eE/c/TMYg8hlAOvI6JP4KmwLgJ4qD0TIbli' \
            'TB+sunjkbeLekKsZ6Zc8V027aBRoBRHVoduDiSypmGFG7CrcBEyDHA0ZNfNphC0D' \
            '6amYa6ANw3YbWD4Pn3oIc+EdL36V3od0A+MaMAXmA8x2Zyn+IQeQeBDfRcUw3B+2' \
            'PxwZ/EdtTDpCPQLMh9TKx0k3pXipEVlknsf5KoNzGyOe1sz8nvYtTQT6yyvTjIax' \
            'smHGB9pFx4n3jIEfDePQvCIrnn0J4B/gA5J4XcRfu4JZuRAw3C51OtOjM3l2bMb8' \
            'Br5eXCsT/w/EAAAAASUVORK5CYII='

base64_img_bytes = base64_img.encode('utf-8')
with open('decoded_image.png', 'wb') as file_to_save:
    decoded_image_data = base64.decodebytes(base64_img_bytes)
    file_to_save.write(decoded_image_data)

En el código anterior, primero convertimos nuestros datos de cadena Base64 en un objeto similar a bytes que se puede decodificar. Cuando está decodificando en base64 un archivo binario, debe saber el tipo de datos que se están decodificando. Por ejemplo, estos datos solo son válidos como archivo PNG y no como archivo MP3, ya que codifican una imagen.

Una vez que el archivo de destino está abierto, decodificamos en Base64 los datos con base64.decodebytes, un método diferente de base64.b64decode que se usaba con cadenas. Este método debe usarse para decodificar datos binarios. Finalmente, escribimos los datos decodificados en un archivo.

En el mismo directorio en el que ejecutó decoding_binary.py, ahora verá un nuevo archivo decoded_image.png que contiene la imagen original que se codificó anteriormente.

Conclusión

La codificación Base64 es una técnica popular para convertir datos en diferentes formatos binarios a una cadena de caracteres ASCII. Esto es útil cuando se transmiten datos a redes o aplicaciones que no pueden procesar datos binarios sin procesar pero que manejarían texto fácilmente.

Con Python, podemos usar el módulo base64 para codificar y decodificar texto y datos binarios en Base64.

¿Qué aplicaciones usaría para codificar y decodificar datos Base64?