Zgodnie z tym przykładem w języku Python koduję ciąg znaków jako Base64 za pomocą:
>>> import base64
>>> encoded = base64.b64encode(b'data to be encoded')
>>> encoded
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Ale jeśli pominę wiodące b
:
>>> encoded = base64.b64encode('data to be encoded')
Otrzymuję następujący błąd:
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
Dlaczego to?
python
python-3.x
base64
dublintech
źródło
źródło
Odpowiedzi:
base64 kodowania trwa 8-bitowy binarny bajt danych i koduje używa tylko znaków
A-Z
,a-z
,0-9
,+
,/
* więc może być transmitowany przez kanały, które nie zachowują wszystkie 8 bitów danych, takich jak e-mail.Dlatego chce ciąg 8-bitowych bajtów. Tworzysz je w Pythonie 3 za pomocą
b''
składni.Jeśli usuniesz
b
, staje się ciąg. Ciąg jest sekwencją znaków Unicode. base64 nie ma pojęcia, co zrobić z danymi Unicode, nie jest to 8-bit. Tak naprawdę to nie są żadne bity. :-)W twoim drugim przykładzie:
Wszystkie znaki dobrze pasują do zestawu znaków ASCII, dlatego kodowanie base64 jest w rzeczywistości trochę bezcelowe. Zamiast tego możesz przekonwertować go na ascii za pomocą
Lub prościej:
Co byłoby identyczne w tym przypadku.
* Większość smaków base64 może również zawierać
=
na końcu jako dopełnienie. Ponadto niektóre warianty base64 mogą używać znaków innych niż+
i/
. Przegląd znajduje się w tabeli podsumowującej warianty na Wikipedii.źródło
Krótka odpowiedź
Trzeba wcisnąć
bytes-like
obiekt (bytes
,bytearray
, etc) dobase64.b64encode()
metody. Oto dwa sposoby:Lub ze zmienną:
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źmieszstring
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ą tobase64
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:
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 ):
base64
kodowanie spowoduje jednak ponowne grupowanie tych danych: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ęcbase64
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:
Dlaczego warto korzystać z
base64
kodowania?Powiedzmy, że muszę przesłać komuś jakieś dane pocztą e-mail, takie jak te dane:
Zasadziłem dwa problemy:
\x04
odczytaniu znaku, ponieważ jest to ASCII dlaEND-OF-TRANSMISSION
(Ctrl-D), więc pozostałe dane zostałyby pominięte w transmisji.BACKSPACE
znaków i trzechSPACE
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.
źródło
base64.b64encode(s.encode()).decode()
nie jest bardzo pytoniczny, kiedy wszystko, czego potrzebujesz, to konwersja łańcucha na łańcuch.base64.encode(s)
powinno wystarczyć przynajmniej w python3. Dzięki za bardzo dobre wyjaśnienie ciągów i bajtów w pythoniebase64.encode(s)
nie działałby w Python3; czy mówisz, że coś takiego powinno być dostępne? Myślę, że powodem tego może być zamieszanie, ponieważ w zależności od kodowania i zawartości łańcuchas
może nie mieć 1 unikatowej reprezentacji jako tablicy bajtów.Jeśli dane, które mają być zakodowane, zawierają znaki „egzotyczne”, myślę, że musisz zakodować w „UTF-8”
źródło
Jeśli ciąg jest Unicode, najprostszym sposobem jest:
źródło
Jest wszystko, czego potrzebujesz:
Prowadzenie
b
sprawia, że Twój ciąg binarny.Jakiej wersji Pythona używasz? 2.x czy 3.x?
Edycja: Zobacz http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit, aby uzyskać szczegółowe informacje na temat ciągów znaków w Pythonie 3.x
źródło
To b oznacza po prostu, że pobierasz dane jako bajty lub tablicę bajtów, a nie jako ciąg.
źródło