base64 — Codificar datos binarios con ASCII¶
Propósito: | El módulo base64 contiene funciones para traducir datos binarios en un subconjunto de ASCII adecuado para la transmisión utilizando protocolos de texto plano. |
---|
Las codificaciones base64, base32, base16 y base85 convierten bytes de 8 bits a valores que caben dentro del rango de caracteres imprimibles ASCII, cambiando más bits para representar los datos de compatibilidad con los sistemas que solo admiten datos ASCII, como SMTP. Los valores base corresponden a la longitud del alfabeto utilizado en cada codificación. Hay también variaciones URL seguras de las codificaciones originales que utilizan alfabetos ligeramente diferentes.
Codificación Base 64¶
Este es un ejemplo básico de codificación de un texto.
import base64
import textwrap
# Load this source file and strip the header.
with open(__file__, 'r', encoding='utf-8') as input:
raw = input.read()
initial_data = raw.split('#end_pymotw_header')[1]
byte_string = initial_data.encode('utf-8')
encoded_data = base64.b64encode(byte_string)
num_initial = len(byte_string)
# There will never be more than 2 padding bytes.
padding = 3 - (num_initial % 3)
print('{} bytes before encoding'.format(num_initial))
print('Expect {} padding bytes'.format(padding))
print('{} bytes after encoding\n'.format(len(encoded_data)))
print(encoded_data)
La entrada debe ser una cadena de bytes, por lo que la cadena Unicode es la codificada primero a UTF-8. La salida muestra los 185 bytes de la fuente UTF-8 expandida a 248 bytes después de ser codificada.
Nota
No hay retornos de carro en los datos codificados producidos por la biblioteca, pero la salida se ha envuelto artificialmente para que encaje mejor en la página.
$ python3 base64_b64encode.py
184 bytes before encoding
Expect 2 padding bytes
248 bytes after encoding
b'CmltcG9ydCBiYXNlNjQKaW1wb3J0IHRleHR3cmFwCgojIExvYWQgdGhpcyBzb3
VyY2UgZmlsZSBhbmQgc3RyaXAgdGhlIGhlYWRlci4Kd2l0aCBvcGVuKF9fZmlsZV
9fLCAncicsIGVuY29kaW5nPSd1dGYtOCcpIGFzIGlucHV0OgogICAgcmF3ID0gaW
5wdXQucmVhZCgpCiAgICBpbml0aWFsX2RhdGEgPSByYXcuc3BsaXQoJw=='
Decodificación de base 64¶
b64decode()
convierte una cadena codificada a la forma original tomando
cuatro bytes y convirtiéndolos a los tres originales, usando un tabla de
búsqueda.
import base64
encoded_data = b'VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWFyLg=='
decoded_data = base64.b64decode(encoded_data)
print('Encoded :', encoded_data)
print('Decoded :', decoded_data)
El proceso de codificación mira cada secuencia de 24 bits en la entrada (tres bytes) y codifica esos mismos 24 bits distribuidos en cuatro bytes en la salida. Los signos de igualdad al final de la salida son relleno insertado porque el número de bits en la cadena original no era uniformemente divisible por 24, en este ejemplo.
$ python3 base64_b64decode.py
Encoded : b'VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWFyLg=='
Decoded : b'This is the data, in the clear.'
El valor devuelto desde b64decode()
es una cadena de bytes. Si se sabe que
los contenidos son texto, la cadena de bytes se puede convertir en un objeto
unicode. Sin embargo, el punto de usar la codificación de base 64 es ser capaz
de transmitir datos binarios, por lo que no siempre es seguro asumir que el
valor decodificado es texto.
Variaciones URL seguras¶
Debido a que el alfabeto base64 predeterminado puede usar +
y /
, y esos
dos caracteres se usan en las URLs, a menudo es necesario usar una codificación
alternativa con sustitutos para esos caracteres.
import base64
encodes_with_pluses = b'\xfb\xef'
encodes_with_slashes = b'\xff\xff'
for original in [encodes_with_pluses, encodes_with_slashes]:
print('Original :', repr(original))
print('Standard encoding:',
base64.standard_b64encode(original))
print('URL-safe encoding:',
base64.urlsafe_b64encode(original))
print()
El +
se reemplaza con un -
, y el /
se reemplaza con guión bajo
(_
). De lo contrario, el alfabeto es el mismo.
$ python3 base64_urlsafe.py
Original : b'\xfb\xef'
Standard encoding: b'++8='
URL-safe encoding: b'--8='
Original : b'\xff\xff'
Standard encoding: b'//8='
URL-safe encoding: b'__8='
Otras codificaciones¶
Además de Base64, el módulo proporciona funciones para trabajar con datos codificados Base85, Base32, y Base16 (hex).
import base64
original_data = b'This is the data, in the clear.'
print('Original:', original_data)
encoded_data = base64.b32encode(original_data)
print('Encoded :', encoded_data)
decoded_data = base64.b32decode(encoded_data)
print('Decoded :', decoded_data)
El alfabeto Base32 incluye las 26 letras mayúsculas del ASCII y los dígitos del 2 al 7.
$ python3 base64_base32.py
Original: b'This is the data, in the clear.'
Encoded : b'KRUGS4ZANFZSA5DIMUQGIYLUMEWCA2LOEB2GQZJAMNWGKYLSFY==
===='
Decoded : b'This is the data, in the clear.'
Las funciones Base16 funcionan con el alfabeto hexadecimal.
import base64
original_data = b'This is the data, in the clear.'
print('Original:', original_data)
encoded_data = base64.b16encode(original_data)
print('Encoded :', encoded_data)
decoded_data = base64.b16decode(encoded_data)
print('Decoded :', decoded_data)
Cada vez que el número de bits de codificación disminuye, la salida en el formato codificado ocupa más espacio.
$ python3 base64_base16.py
Original: b'This is the data, in the clear.'
Encoded : b'546869732069732074686520646174612C20696E207468652063
6C6561722E'
Decoded : b'This is the data, in the clear.'
Las funciones Base85 usan un alfabeto expandido que es más eficiente en espacio que la base 64.
import base64
original_data = b'This is the data, in the clear.'
print('Original : {} bytes {!r}'.format(
len(original_data), original_data))
b64_data = base64.b64encode(original_data)
print('b64 Encoded : {} bytes {!r}'.format(
len(b64_data), b64_data))
b85_data = base64.b85encode(original_data)
print('b85 Encoded : {} bytes {!r}'.format(
len(b85_data), b85_data))
a85_data = base64.a85encode(original_data)
print('a85 Encoded : {} bytes {!r}'.format(
len(a85_data), a85_data))
Existen varias codificaciones Base85 y se utilizan diferentes variaciones en
Mercurial, git, y el formato de archivo PDF. Python incluye dos
implementaciones, b85encode()
implementa la versión usada en Git y
Mercurial mientras a85encode()
implementa la variante Ascii85 utilizada por
los archivos PDF.
$ python3 base64_base85.py
Original : 31 bytes b'This is the data, in the clear.'
b64 Encoded : 44 bytes b'VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWF
yLg=='
b85 Encoded : 39 bytes b'RA^~)AZc?TbZBKDWMOn+EFfuaAarPDAY*K0VR9}
'
a85 Encoded : 39 bytes b'<+oue+DGm>FD,5.A79Rg/0JYE+EV:.+Cf5!@<*t
'
Ver también
- Documentación de la biblioteca estándar para base64
- RFC 3548 – Las codificaciones de datos Base16, Base32, y Base64
- RFC 1924 – Una representación compacta de direcciones IPv6 (sugiere la codificación de base 85 para direcciones de red IPv6)
- Ascii85
- Notas para portar Python 2 a 3 para base64