Seguindo este exemplo de python , codifico uma string como Base64 com:
>>> import base64
>>> encoded = base64.b64encode(b'data to be encoded')
>>> encoded
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Mas, se eu deixar de fora a liderança b
:
>>> encoded = base64.b64encode('data to be encoded')
Estou tendo o erro a seguir:
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 que é isso?
python
python-3.x
base64
dublintech
fonte
fonte
Respostas:
base64 codificação leva de 8 bits de dados byte binários e codifica utiliza apenas os personagens
A-Z
,a-z
,0-9
,+
,/
* para que ele possa ser transmitido através de canais que não preservam todos os 8-bits de dados, tais como e-mail.Portanto, ele deseja uma sequência de bytes de 8 bits. Você cria aqueles no Python 3 com a
b''
sintaxe.Se você remover o
b
, ele se tornará uma sequência. Uma sequência é uma sequência de caracteres Unicode. base64 não tem idéia do que fazer com dados Unicode, não é de 8 bits. Na verdade, não é nenhum pedaço. :-)No seu segundo exemplo:
Todos os caracteres se encaixam perfeitamente no conjunto de caracteres ASCII e, portanto, a codificação base64 é um pouco inútil. Você pode convertê-lo para ascii, com
Ou mais simples:
O que seria a mesma coisa neste caso.
* A maioria dos sabores base64 também pode incluir um
=
no final como preenchimento. Além disso, algumas variantes de base64 podem usar caracteres diferentes de+
e/
. Veja a tabela de resumo de variantes na Wikipedia para uma visão geral.fonte
Resposta curta
É necessário empurrar um
bytes-like
objecto (bytes
,bytearray
, etc.) para obase64.b64encode()
método. Aqui estão duas maneiras:Ou com uma variável:
Por quê?
Em Python 3,
str
objectos não são matrizes de caracteres de estilo C (de modo que eles são não byte matrizes), mas em vez disso, eles são estruturas de dados que não têm qualquer codificação inerente. Você pode codificar essa sequência (ou interpretá-la) de várias maneiras. O mais comum (e o padrão no Python 3) é o utf-8, especialmente porque é compatível com o ASCII (embora, como as codificações mais usadas). É o que está acontecendo quando você pega umstring
e chama o.encode()
método: Python está interpretando a string em utf-8 (a codificação padrão) e fornecendo a matriz de bytes a que corresponde.Codificação Base-64 em Python 3
Originalmente, o título da pergunta era sobre a codificação Base-64. Leia sobre as coisas da Base-64.
base64
a codificação pega pedaços binários de 6 bits e os codifica usando os caracteres AZ, az, 0-9, '+', '/' e '=' (algumas codificações usam caracteres diferentes no lugar de '+' e '/') . Essa é uma codificação de caracteres baseada na construção matemática do sistema de números radix-64 ou base-64, mas eles são muito diferentes. A base-64 em matemática é um sistema numérico como binário ou decimal, e você faz essa alteração de raiz em todo o número, ou (se a raiz da qual você está convertendo for uma potência de 2 menor que 64) em pedaços da direita para esquerda.Na
base64
codificação, a tradução é feita da esquerda para a direita; esses primeiros 64 caracteres são o motivo pelo qual é chamado debase64
codificação . O 65º símbolo '=' é usado para preenchimento, pois a codificação extrai pedaços de 6 bits, mas os dados que costuma codificar são bytes de 8 bits, portanto, às vezes, existem apenas dois ou 4 bits no último pedaço.Exemplo:
Se você interpretar esses dados binários como um único número inteiro, é assim que você os converteria em base 10 e base 64 ( tabela para base 64 ):
base64
A codificação , no entanto, agrupará novamente esses dados:Portanto, 'B0ZXN0' é a versão base 64 do nosso binário, matematicamente falando. No entanto, a
base64
codificação deve fazer a codificação na direção oposta (para que os dados brutos sejam convertidos em 'dGVzdA') e também possui uma regra para informar a outras aplicações quanto espaço resta no final. Isso é feito preenchendo o final com símbolos '='. Portanto, abase64
codificação desses dados é 'dGVzdA ==', com dois símbolos '=' para indicar que dois pares de bits precisarão ser removidos do final quando esses dados forem decodificados para que correspondam aos dados originais.Vamos testar isso para ver se estou sendo desonesto:
Por que usar
base64
codificação?Digamos que eu tenho que enviar alguns dados para alguém por email, como esses dados:
Existem dois problemas que plantei:
\x04
caractere fosse lido, porque é ASCII paraEND-OF-TRANSMISSION
(Ctrl-D), para que os dados restantes fiquem de fora da transmissão.BACKSPACE
caracteres e trêsSPACE
caracteres para apagar o 'msg'. Assim, mesmo se eu não tivesse oEOF
personagem, o usuário final não seria capaz de traduzir do texto na tela para os dados reais e brutos.Esta é apenas uma demonstração para mostrar o quão difícil pode ser simplesmente enviar dados brutos. A codificação dos dados no formato base64 fornece exatamente os mesmos dados, mas em um formato que garante a segurança do envio por mídia eletrônica, como email.
fonte
base64.b64encode(s.encode()).decode()
não é muito pitonico quando tudo o que você quer é uma conversão de string para string.base64.encode(s)
deve ser suficiente pelo menos em python3. Obrigado por uma explicação muito boa sobre seqüências de caracteres e bytes em pythonbase64.encode(s)
não funcionaria em Python3; você está dizendo que algo assim deveria estar disponível? Eu acho que a razão pela qual isso pode ser confuso é que, dependendo da codificação e do conteúdo da string,s
talvez não tenha uma representação única como uma matriz de bytes.Se os dados a serem codificados contiverem caracteres "exóticos", acho que você precisará codificar em "UTF-8"
fonte
Se a string for Unicode, a maneira mais fácil é:
fonte
Tudo o que você precisa:
A liderança
b
torna sua string binária.Qual versão do Python você usa? 2.x ou 3.x?
Edit: Veja http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit para obter os detalhes sangrentos das seqüências de caracteres em Python 3.x
fonte
Isso b significa simplesmente que você está recebendo entrada como uma matriz de bytes ou bytes, não como uma string.
fonte