Siguiendo este ejemplo de Python , codifico una cadena como Base64 con:
>>> import base64
>>> encoded = base64.b64encode(b'data to be encoded')
>>> encoded
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Pero, si dejo de lado el líder b
:
>>> encoded = base64.b64encode('data to be encoded')
Obtuve el siguiente error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python32\lib\base64.py", line 56, in b64encode
raise TypeError("expected bytes, not %s" % s.__class__.__name__)
TypeError: expected bytes, not str
¿Por qué es esto?
python
python-3.x
base64
dublintech
fuente
fuente
Respuestas:
codificación Base64 tiene 8 bits de datos binarios de bytes y lo codifica utiliza sólo los caracteres
A-Z
,a-z
,0-9
,+
,/
* para que pueda ser transmitida a través de canales que no conservan los 8 bits de datos, tales como correo electrónico.Por lo tanto, quiere una cadena de bytes de 8 bits. Los creas en Python 3 con la
b''
sintaxis.Si elimina el
b
, se convierte en una cadena. Una cadena es una secuencia de caracteres Unicode. base64 no tiene idea de qué hacer con los datos Unicode, no es de 8 bits. En realidad no es nada, de hecho. :-)En tu segundo ejemplo:
Todos los caracteres encajan perfectamente en el conjunto de caracteres ASCII y, por lo tanto, la codificación base64 es en realidad un poco inútil. En su lugar, puede convertirlo a ASCII, con
O más simple:
Lo 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 distintos de+
y/
. Consulte la tabla de resumen de Variantes en Wikipedia para obtener una descripción general.fuente
Respuesta corta
Es necesario para empujar un
bytes-like
objeto (bytes
,bytearray
, etc.) albase64.b64encode()
método. Aquí hay dos formas:O con una variable:
¿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 unstring
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 llamabase64
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:
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 ):
base64
la codificación , sin embargo, reagrupará estos datos de esta manera: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, labase64
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:
¿Por qué usar
base64
codificación?Digamos que tengo que enviar algunos datos a alguien por correo electrónico, como estos datos:
Hay dos problemas que planté:
\x04
se leyera el carácter, ya que es ASCII paraEND-OF-TRANSMISSION
(Ctrl-D), por lo que los datos restantes quedarían fuera de la transmisión.BACKSPACE
caracteres y tresSPACE
caracteres para borrar el 'mensaje'. Por lo tanto, incluso si no tuviera elEOF
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.
fuente
base64.b64encode(s.encode()).decode()
no es muy pitónico cuando todo lo que quieres es una conversión de cadena a cadena.base64.encode(s)
debería ser suficiente al menos en python3. Gracias por una muy buena explicación sobre cadenas y bytes en pythonbase64.encode(s)
no funcionaría en Python3; ¿Estás diciendo que algo así debería estar disponible? Creo que la razón por la que puede ser confuso es que, dependiendo de la codificación y el contenido de la cadena,s
podría no tener 1 representación única como una matriz de bytes.Si los datos a codificar contienen caracteres "exóticos", creo que debe codificar en "UTF-8"
fuente
Si la cadena es Unicode, la forma más fácil es:
fuente
Hay todo lo que necesitas:
La guía
b
hace que su cadena sea binaria.¿Qué versión de Python usas? 2.xo 3.x?
Editar: consulte http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit para ver los detalles sangrientos de las cadenas en Python 3.x
fuente
Eso b simplemente significa que está tomando la entrada como una matriz de bytes o bytes, no como una cadena.
fuente