Risposta breve
È necessario spingere un bytes-like
oggetto ( bytes
, bytearray
, ecc) per il base64.b64encode()
metodo. Ecco due modi:
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
O con una variabile:
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Perché?
In Python 3, str
oggetti non sono array di caratteri in stile C (in modo che siano non byte array), ma piuttosto, sono strutture di dati che non hanno alcuna codifica inerente. Puoi codificare quella stringa (o interpretarla) in vari modi. Il più comune (e predefinito in Python 3) è utf-8, soprattutto perché è retrocompatibile con ASCII (sebbene, come lo sono le codifiche più utilizzate). Questo è ciò che accade quando si prende un string
e si chiama il .encode()
metodo su di esso: Python sta interpretando la stringa in utf-8 (la codifica predefinita) e ti fornisce l'array di byte a cui corrisponde.
Codifica Base 64 in Python 3
Inizialmente il titolo della domanda poneva domande sulla codifica Base-64. Continua a leggere per roba Base-64.
base64
la codifica accetta blocchi binari a 6 bit e li codifica utilizzando i caratteri AZ, az, 0-9, '+', '/' e '=' (alcune codifiche usano caratteri diversi al posto di '+' e '/') . Questa è una codifica dei caratteri che si basa sul costrutto matematico del sistema numerico radix-64 o base-64, ma sono molto diversi. Base-64 in matematica è un sistema numerico come binario o decimale, e fai questo cambio di radix sull'intero numero o (se il radix da cui stai convertendo è una potenza di 2 in meno di 64) in blocchi da destra a sinistra.
Nella base64
codifica, la traduzione viene eseguita da sinistra a destra; quei primi 64 caratteri sono il motivo per cui si chiama base64
codifica . Il 65 ° simbolo '=' viene utilizzato per il riempimento, poiché la codifica estrae blocchi di 6 bit ma i dati che di solito intende codificare sono byte di 8 bit, quindi a volte ci sono solo due o 4 bit nell'ultimo blocco.
Esempio:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
Se interpretate quei dati binari come un singolo intero, allora è così che li convertireste in base-10 e base-64 ( tabella per 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 codifica , tuttavia, raggrupperà nuovamente questi dati in questo modo:
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
Quindi, 'B0ZXN0' è la versione base 64 del nostro binario, matematicamente parlando. Tuttavia, la base64
codifica deve eseguire la codifica nella direzione opposta (quindi i dati grezzi vengono convertiti in 'dGVzdA') e ha anche una regola per dire ad altre applicazioni quanto spazio viene lasciato alla fine. Questo viene fatto riempiendo la fine con i simboli '='. Quindi, la base64
codifica di questi dati è 'dGVzdA ==', con due simboli '=' per indicare due coppie di bit dovranno essere rimossi dalla fine quando questi dati vengono decodificati per farlo corrispondere ai dati originali.
Proviamo questo per vedere se sono disonesto:
>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='
Perché usare la base64
codifica?
Diciamo che devo inviare alcuni dati a qualcuno via e-mail, come questi dati:
>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())
>>> print(data)
b'\x04msg\x08\x08\x08 '
>>>
Ci sono due problemi che ho piantato:
- Se provassi a inviare quell'e-mail in Unix, l'e-mail verrebbe inviata non appena il
\x04
carattere veniva letto, perché quello è ASCII per END-OF-TRANSMISSION
(Ctrl-D), quindi i dati rimanenti sarebbero lasciati fuori dalla trasmissione.
- Inoltre, mentre Python è abbastanza intelligente da sfuggire a tutti i miei personaggi di controllo malvagio quando stampo direttamente i dati, quando quella stringa viene decodificata come ASCII, puoi vedere che "msg" non è presente. Questo perché ho usato tre
BACKSPACE
caratteri e tre SPACE
caratteri per cancellare "msg". Pertanto, anche se non avessi il EOF
personaggio lì, l'utente finale non sarebbe in grado di tradurre dal testo sullo schermo ai dati reali e non elaborati.
Questa è solo una demo per mostrare quanto sia difficile inviare semplicemente dati non elaborati. La codifica dei dati nel formato base64 fornisce esattamente gli stessi dati, ma in un formato che garantisce che sia sicuro per l'invio su supporti elettronici come l'e-mail.