Krótka odpowiedź
Trzeba wcisnąć bytes-like
obiekt ( bytes
, bytearray
, etc) do base64.b64encode()
metody. Oto dwa sposoby:
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Lub ze zmienną:
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Czemu?
W Pythonie 3, str
obiekty nie są tablice znaków w stylu C (więc są one nie bajt tablic), ale raczej są struktury danych, które nie mają żadnego kodowania wrodzoną. Możesz zakodować ten ciąg (lub zinterpretować go) na różne sposoby. Najczęstszym (i domyślnym w Pythonie 3) jest utf-8, zwłaszcza, że jest wstecznie kompatybilny z ASCII (chociaż, jak to są najczęściej stosowane kodowania). Tak dzieje się, gdy weźmiesz string
i wywołasz na nim .encode()
metodę: Python interpretuje ciąg znaków w utf-8 (kodowanie domyślne) i zapewnia tablicę bajtów, z którą odpowiada.
Kodowanie Base-64 w Pythonie 3
Pierwotnie pytanie brzmiało na temat kodowania Base-64. Czytaj dalej na temat Base-64.
base64
kodowanie zajmuje 6-bitowe binarne fragmenty i koduje je przy użyciu znaków AZ, az, 0-9, „+”, „/” i „=” (niektóre kodowania używają różnych znaków zamiast „+” i „/”) . Jest to kodowanie znaków oparte na matematycznej konstrukcji systemu liczbowego Radix-64 lub base-64, ale są one bardzo różne. Base-64 w matematyce to system liczbowy, taki jak binarny lub dziesiętny, i dokonuje się tej zmiany podstawki na całej liczbie lub (jeśli podstawa, z której przeliczamy, jest potęgą 2 mniejszą niż 64) w częściach od prawej do lewo.
W base64
kodowaniu tłumaczenie odbywa się od lewej do prawej; te pierwsze 64 znaki nazywają to base64
kodowaniem . Symbol 65. „=” jest używany do wypełniania, ponieważ kodowanie ściąga 6-bitowe porcje, ale dane, które zwykle mają być kodowane, to 8-bitowe bajty, więc czasami w ostatnim fragmencie są tylko dwa lub 4 bity.
Przykład:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
Jeśli interpretujesz te dane binarne jako pojedynczą liczbę całkowitą, to w ten sposób przekonwertujesz je na base-10 i base-64 ( tabela dla 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
kodowanie spowoduje jednak ponowne grupowanie tych danych:
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
Tak więc „B0ZXN0” jest matematyczną wersją naszej bazy binarnej w wersji 64. Jednak base64
kodowanie musi zrobić kodowanie w kierunku przeciwnym (tak surowe dane przekształca się w „dGVzdA”), a także ma reguły do powiedzenia inne aplikacje ile miejsca zostało przerwane na końcu. Odbywa się to poprzez wypełnienie końca symbolami „=”. Tak więc base64
kodowanie tych danych to „dGVzdA ==”, a dwa symbole „=” oznaczające dwie pary bitów będą musiały zostać usunięte od końca, gdy dane te zostaną zdekodowane, aby dopasować je do pierwotnych danych.
Przetestujmy to, aby sprawdzić, czy jestem nieuczciwy:
>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='
Dlaczego warto korzystać z base64
kodowania?
Powiedzmy, że muszę przesłać komuś jakieś dane pocztą e-mail, takie jak te dane:
>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())
>>> print(data)
b'\x04msg\x08\x08\x08 '
>>>
Zasadziłem dwa problemy:
- Gdybym próbował wysłać tę wiadomość e-mail w systemie Unix, wiadomość e-mail zostałaby wysłana natychmiast po
\x04
odczytaniu znaku, ponieważ jest to ASCII dla END-OF-TRANSMISSION
(Ctrl-D), więc pozostałe dane zostałyby pominięte w transmisji.
- Ponadto, podczas gdy Python jest wystarczająco inteligentny, aby uciec przed wszystkimi moimi złymi znakami kontroli, gdy drukuję dane bezpośrednio, gdy ten ciąg jest dekodowany jako ASCII, widać, że nie ma „msg”. Jest tak, ponieważ użyłem trzech
BACKSPACE
znaków i trzech SPACE
znaków, aby usunąć „msg”. Dlatego nawet gdybym nie miał EOF
tam znaku, użytkownik końcowy nie byłby w stanie przetłumaczyć tekstu z ekranu na prawdziwe, surowe dane.
To tylko wersja demonstracyjna pokazująca, jak trudno może być po prostu wysłać surowe dane. Kodowanie danych w formacie base64 daje dokładnie te same dane, ale w formacie zapewniającym bezpieczeństwo przesyłania za pośrednictwem mediów elektronicznych, takich jak poczta elektroniczna.