Este equipo especializado despúes de varios días de investigación y recopilación de de datos, han obtenido la solución, nuestro deseo es que te sea útil para tu plan.
Solución:
La codificación base64 toma datos de bytes binarios de 8 bits y los codifica, usa solo los caracteres A-Z
, a-z
, 0-9
, +
, /
* para que pueda transmitirse a través de canales que no conservan todos los 8 bits de datos, como el correo electrónico.
Por lo tanto, quiere un string de bytes de 8 bits. Los creas en Python 3 con el b''
sintaxis.
Si quitas el b
se convierte en un string. A string es una secuencia de caracteres Unicode. base64 no tiene idea de qué hacer con los datos Unicode, no son de 8 bits. De hecho, no es ningún bit. 🙂
En tu segundo ejemplo:
>>> encoded = base64.b64encode('data to be encoded')
Todos los caracteres encajan perfectamente en el conjunto de caracteres ASCII y, por lo tanto, la codificación base64 es un poco inútil. Puede convertirlo a ascii en su lugar, con
>>> encoded = 'data to be encoded'.encode('ascii')
O más simple:
>>> encoded = b'data to be encoded'
Que sería lo mismo en este caso.
* La mayoría de los sabores base64 también pueden incluir un =
al final como relleno. Además, algunas variantes de base64 pueden usar caracteres que no sean +
y /
. Consulte la tabla de resumen de variantes en Wikipedia para obtener una descripción general.
Respuesta corta
Tienes que empujar un bytes-like
objeto (bytes
, bytearray
etc) a la base64.b64encode()
método. Aquí hay dos formas:
>>> import base64
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
O con una variable:
>>> import base64
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
¿Por qué?
En Python 3, str
Los objetos no son matrices de caracteres de estilo C (por lo que son no matrices de bytes), sino que son estructuras de datos que no tienen ninguna codificación inherente. Puedes codificar eso string (o interpretarlo) en una variedad de formas. El más común (y predeterminado en Python 3) es utf-8, especialmente porque es retrocompatible con ASCII (aunque, al igual que las codificaciones más utilizadas). Eso es lo que sucede cuando tomas un string
y llama al .encode()
método en él: Python está interpretando el string en utf-8 (la codificación predeterminada) y brindándole la array de bytes que le corresponde.
Codificación Base-64 en Python 3
Originalmente, el título de la pregunta se refería a la codificación Base-64. Siga leyendo para conocer las cosas de Base-64.
base64
la codificación toma fragmentos binarios de 6 bits y los codifica usando los caracteres AZ, az, 0-9, ‘+’, ‘/’ y ‘=’ (algunas codificaciones usan diferentes caracteres en lugar de ‘+’ y ‘/’) . Esta es una codificación de caracteres que se basa en la construcción matemática del sistema numérico radix-64 o base-64, pero son muy diferentes. Base-64 en matemáticas es un sistema numérico como binario o decimal, y haces este cambio de base en el número completo, o (si la base de la que estás convirtiendo es una potencia de 2 menos que 64) en partes de derecha a izquierda.
En 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 ‘=’ número 65 se usa para el relleno, ya que la codificación extrae fragmentos de 6 bits, pero los datos que normalmente 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, así es como los convertiría a 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
codificaciónsin embargo, reagrupará estos datos de la siguiente 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, base64
codificación tiene que hacer la codificación en la dirección opuesta (para que los datos sin procesar se conviertan a 'dGVzdA') y también tiene una regla para decirle a otras aplicaciones cuánto espacio queda al final. Esto se hace rellenando el final con los símbolos '='. Entonces el base64
la 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 que usar base64
codificación?
Digamos que tengo que enviar algunos datos a alguien por correo electrónico, como estos datos:
>>> data = b'x04x6dx73x67x08x08x08x20x20x20'
>>> print(data.decode())
>>> print(data)
b'x04msgx08x08x08 '
>>>
Hay dos problemas que planteé:
- Si intentara enviar ese correo electrónico en Unix, el correo electrónico se enviaría tan pronto como el
x04
se leyó el carácter, porque eso es ASCII paraEND-OF-TRANSMISSION
(Ctrl-D), por lo que los datos restantes quedarían fuera de la transmisión. - Además, aunque Python es lo suficientemente inteligente como para escapar de todos mis personajes de control malvados cuando imprimo los datos directamente, cuando eso string está decodificado como ASCII, puede ver que el 'msg' no está allí. Eso es porque usé tres
BACKSPACE
personajes y tresSPACE
caracteres para borrar el 'msg'. Por lo tanto, incluso si no tuviera laEOF
carácter allí, el usuario final no podría traducir del texto en pantalla a los datos reales sin procesar.
Esta es solo una demostración para mostrarle lo difícil que puede ser simplemente enviar datos sin procesar. La codificación de los datos en formato base64 le brinda exactamente los mismos datos pero en un formato que garantiza que sea seguro para enviar por medios electrónicos como el correo electrónico.
Si los datos a codificar contienen caracteres "exóticos", creo que hay que codificarlos en "UTF-8"
encoded = base64.b64encode (bytes('data to be encoded', "utf-8"))
Si estás de acuerdo, tienes el poder dejar una noticia acerca de qué le añadirías a este tutorial.