Respuesta corta
Es necesario para empujar un bytes-like
objeto ( bytes
, bytearray
, etc.) al base64.b64encode()
método. Aquí hay dos formas:
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
O con una variable:
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
¿Por qué?
En Python 3, los str
objetos no son matrices de caracteres de estilo C (por lo que no son matrices de bytes), sino estructuras de datos que no tienen ninguna codificación inherente. Puede codificar esa cadena (o interpretarla) de varias maneras. El más común (y predeterminado en Python 3) es utf-8, especialmente porque es compatible con versiones anteriores de ASCII (aunque, como son las codificaciones más utilizadas). Eso es lo que está sucediendo cuando toma un string
y llama al .encode()
método: Python está interpretando la cadena en utf-8 (la codificación predeterminada) y le proporciona la matriz de bytes a la que corresponde.
Codificación Base-64 en Python 3
Originalmente, el título de la pregunta era sobre la codificación Base-64. Siga leyendo para obtener información sobre Base-64.
base64
la codificación toma fragmentos binarios de 6 bits y los codifica con los caracteres AZ, az, 0-9, '+', '/' y '=' (algunas codificaciones usan caracteres diferentes en lugar de '+' y '/') . Esta es una codificación de caracteres que se basa en la construcción matemática del sistema de números radix-64 o base-64, pero son muy diferentes. Base-64 en matemáticas es un sistema numérico como binario o decimal, y usted hace este cambio de radix en todo el número, o (si la radix de la que está convirtiendo es una potencia de 2 menor que 64) en trozos de derecha a izquierda.
En la base64
codificación, la traducción se realiza de izquierda a derecha; esos primeros 64 caracteres son la razón por la que se llama base64
codificación . El símbolo 65 '=' se usa para el relleno, ya que la codificación extrae fragmentos de 6 bits, pero los datos que generalmente debe codificar son bytes de 8 bits, por lo que a veces solo hay dos o 4 bits en el último fragmento.
Ejemplo:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
Si interpreta esos datos binarios como un solo entero, entonces así es como los convertiría en base-10 y base-64 ( tabla para base-64 ):
base-2: 01 110100 011001 010111 001101 110100 (base-64 grouping shown)
base-10: 1952805748
base-64: B 0 Z X N 0
base64
la codificación , sin embargo, reagrupará estos datos de esta manera:
base-2: 011101 000110 010101 110011 011101 00(0000) <- pad w/zeros to make a clean 6-bit chunk
base-10: 29 6 21 51 29 0
base-64: d G V z d A
Entonces, 'B0ZXN0' es la versión base 64 de nuestro binario, matemáticamente hablando. Sin embargo, la base64
codificación tiene que hacer la codificación en la dirección opuesta (por lo que los datos sin procesar se convierten a 'dGVzdA') y también tiene una regla para indicar a otras aplicaciones cuánto espacio queda al final. Esto se hace rellenando el final con símbolos '='. Entonces, la base64
codificación de estos datos es 'dGVzdA ==', con dos símbolos '=' para indicar que dos pares de bits deberán eliminarse del final cuando estos datos se decodifiquen para que coincidan con los datos originales.
Probemos esto para ver si estoy siendo deshonesto:
>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='
¿Por qué usar base64
codificación?
Digamos que tengo que enviar algunos datos a alguien por correo electrónico, como estos datos:
>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())
>>> print(data)
b'\x04msg\x08\x08\x08 '
>>>
Hay dos problemas que planté:
- Si intenté enviar ese correo electrónico en Unix, el correo electrónico se enviaría tan pronto como
\x04
se leyera el carácter, ya que es ASCII para END-OF-TRANSMISSION
(Ctrl-D), por lo que los datos restantes quedarían fuera de la transmisión.
- Además, si bien Python es lo suficientemente inteligente como para escapar de todos mis personajes de control malvados cuando imprimo los datos directamente, cuando esa cadena se decodifica como ASCII, puede ver que el 'mensaje' no está allí. Eso es porque usé tres
BACKSPACE
caracteres y tres SPACE
caracteres para borrar el 'mensaje'. Por lo tanto, incluso si no tuviera el EOF
carácter allí, el usuario final no podría traducir del texto en pantalla a los datos reales y sin procesar.
Esta es solo una demostración para mostrarle lo difícil que puede ser simplemente enviar datos sin procesar. Codificar los datos en formato base64 le proporciona exactamente los mismos datos, pero en un formato que garantiza que sea seguro enviarlos por medios electrónicos como el correo electrónico.