Do czego służy kodowanie podstawowe 64?


781

Słyszałem, jak ludzie mówią o „kodowaniu base 64” tu i tam. Do czego jest to używane?


1
Z podręcznika dla base64_encode () : „To kodowanie zostało zaprojektowane, aby dane binarne przetrwały transport przez warstwy transportowe, które nie są 8-bitowe, takie jak treść wiadomości”.
still_dreaming_1

Odpowiedzi:


939

Kiedy masz jakieś dane binarne, które chcesz wysłać przez sieć, zazwyczaj nie robisz tego po prostu przesyłając strumieniowo bity i bajty przez drut w surowym formacie. Dlaczego? ponieważ niektóre media są przeznaczone do przesyłania strumieniowego tekstu. Nigdy nie wiadomo - niektóre protokoły mogą interpretować twoje dane binarne jako znaki kontrolne (jak modem), lub twoje dane binarne mogą zostać zepsute, ponieważ protokół bazowy może myśleć, że wprowadziłeś specjalną kombinację znaków (na przykład sposób, w jaki FTP tłumaczy wiersz zakończenia).

Aby obejść ten problem, ludzie kodują dane binarne w postaciach. Base64 jest jednym z tych typów kodowania.

Dlaczego 64?
Ponieważ ogólnie możesz polegać na tych samych 64 znakach obecnych w wielu zestawach znaków i możesz być całkiem pewny, że Twoje dane nie zostaną uszkodzone po drugiej stronie drutu.


104
(Teoretycznie można wykonać kodowanie base-80 lub coś podobnego, ale byłoby to znacznie trudniejsze. Potęgi dwóch to naturalne zasady dla plików binarnych.)
Jon Skeet,

13
@yokees: Nie ma gwarancji, to tylko postacie, które prawie zawsze są bezpieczne. Dlatego istnieje wiele form Base-64 ( en.wikipedia.org/wiki/Base-64 ).

8
Czy to oznacza, że ​​wszystkie przesyłane dane typu sieci powinny używać pewnego rodzaju kodowania?
Tanner Summers,

6
Ale dlaczego stosuje się metodę base64 do kodowania danych ciągu? np. w funkcji javascript atob Czy serwer ma kodować plik json do formatu base64? Znaki specjalne mogą być przypadkiem użycia, ale dlaczego nie utf8 w takim przypadku, czy są równoważne? Wszelkie dodatkowe informacje na ten temat byłyby bardzo mile widziane, dziękuję.
partizanos

4
Dobrze byłoby mieć listę przynajmniej niektórych protokołów, które zawiodłyby, gdyby ktoś o tym wiedział.
Tadej

202

Jest to w zasadzie sposób kodowania dowolnych danych binarnych w tekście ASCII. Zajmuje 4 znaki na 3 bajty danych, a na końcu może nieco dopełnienia.

Zasadniczo każde 6 bitów wejścia jest kodowane alfabetem 64-znakowym. Alfabet „standardowy” używa AZ, az, 0-9 i + i /, z = jako znak dopełniający. Istnieją warianty bezpieczne dla adresów URL.

Wikipedia jest dość dobrym źródłem więcej informacji.


W języku takim jak php, będą pochodzić dane binarne. Prawie zawsze pracujemy z danymi tekstowymi, które są tekstem.
Cholthi Paul Ttiopic

3
@CholthiPaulTtiopic: Wyniki szyfrowania lub kompresji albo dźwięku / obrazów / wideo.
Jon Skeet,

1
@CholthiPaulTtiopic: Obawiam się, że nie mam pojęcia, co rozumiesz przez „co z przechowywaniem”, ale w tym momencie myślę, że jesteśmy nieco nie na temat.
Jon Skeet,

2
@CholthiPaulTtiopic: Zdecydowanie unikałbym myślenia w kategoriach „ciąg binarny”. Dane binarne powinny być traktowane jako dane binarne, a nie traktowane jak tekst. Widziałem dosłownie setki - być może tysiące - pytań na temat SO, które w zasadzie sprowadzają się do ludzi, którzy nie dbają wystarczająco o to rozróżnienie.
Jon Skeet,

1
@ still_dreaming_1 PHP je wywołuje binary strings. (źródło) php.net/manual/en/function.pack.php
Cholthi Paul Ttiopic


116

Jest to tekstowe kodowanie danych binarnych, w którym wynikowy tekst zawiera wyłącznie litery, cyfry oraz symbole „+”, „/” i „=”. Jest to wygodny sposób na przechowywanie / przesyłanie danych binarnych za pośrednictwem mediów, które są specjalnie używane do danych tekstowych.

Ale dlaczego Base-64? Dwie alternatywy konwersji danych binarnych na tekst, które natychmiast przychodzą mi do głowy:

  1. Dziesiętny: zapisz wartość dziesiętną każdego bajtu jako trzy liczby: 045 112 101 037 itd., Gdzie każdy bajt jest reprezentowany przez 3 bajty. Dane wzdychają trzykrotnie.
  2. Szesnastkowy: przechowuj bajty jako pary szesnastkowe: AC 47 0D 1A itd., Gdzie każdy bajt jest reprezentowany przez 2 bajty. Dane są rozdęte podwójnie.

Base-64 mapuje 3 bajty (8 x 3 = 24 bity) na 4 znaki, które obejmują 6-bitów (6 x 4 = 24 bity). Wynik wygląda mniej więcej tak: „TWFuIGlzIGRpc3Rpb ...”. Dlatego wzdęcia są zaledwie zaledwie 4/3 = 1,3333333 razy większe od oryginału.


10
Czy rozumiem poprawnie, że 64 jest najlepszym wyborem, ponieważ jest to najwyższa z dwóch potęg, którą można przekształcić do postaci drukowalnej ASCII (jest ich 95)?
voho

Jeśli w obu przypadkach są to 24 bity, to czy nie ma wzdęcia 1: 1? Lub kiedy mówisz 4 znaki, które obejmują 6 bitów, czy masz na myśli, że tak naprawdę jest 8 bitów na znak, ale pierwsze dwa są wypełnione zerami?
David Klempfner

1
@Backwards_Dave Każde 6 bitów wyraża się w 8 bitach. Zatem wzdęcia wynoszą 8: 6 lub 4: 3.
Ates Goral

82

Oprócz tego, co już powiedziano, są dwa bardzo częste zastosowania, których nie wymieniono

Hashes:

Hashe to funkcje jednokierunkowe, które przekształcają blok bajtów w inny blok bajtów o ustalonym rozmiarze, taki jak 128-bitowy lub 256-bitowy (SHA / MD5). Konwersja powstałych bajtów na Base64 znacznie ułatwia wyświetlanie skrótu, szczególnie podczas porównywania sumy kontrolnej pod kątem integralności. Hashe są tak często widoczne w Base64, że wiele osób myli samo Base64 jako hash.

Kryptografia:

Ponieważ kluczem szyfrującym nie musi być tekst, ale surowe bajty, czasami konieczne jest przechowywanie go w pliku lub bazie danych, do czego przydaje się Base64. To samo z wynikowymi zaszyfrowanymi bajtami.

Zauważ, że chociaż Base64 jest często używany w kryptografii, nie jest mechanizmem bezpieczeństwa. Każdy może przekonwertować ciąg Base64 z powrotem na oryginalne bajty, więc nie należy go używać jako środka do ochrony danych, a jedynie jako formatu do łatwiejszego wyświetlania lub przechowywania nieprzetworzonych bajtów.

Certyfikaty

Certyfikaty x509 w formacie PEM są zakodowane w standardzie 64. http://how2ssl.com/articles/working_with_pem_files/


4
W rzeczywistości w wielu przypadkach łatwiej jest przetwarzać bajty jako bajty. Nawet w bazie danych, a zwłaszcza w pliku (jeśli używane są rekordy o stałej długości lub bajty są jedyną zawartością). Base64 jest zwykle używany, gdy te bajty mają być gdzieś transmitowane , szczególnie przez kanał, który może odciąć bity lub zinterpretować niektóre bajty jako kody sterujące.
cHao

Nigdy nie widziałem skrótu zapisanego jako liczby całkowite bez znaku, 8, 1, 255,36 ... i wyświetlanie go za pomocą UTF-8 lub innego kodowania nie miałoby sensu, jak inaczej byś go wyświetlał inaczej niż z base64? Klucze szyfrujące i zaszyfrowane dane są często przechowywane w plikach konfiguracyjnych i XML, w których nie można przechowywać nieprzetworzonych bajtów. Zgadzam się, czy możesz przechowywać go jako nieprzetworzone bajty, ale base64 jest dla tych sytuacji, gdy nie możesz. Istnieje wiele zastosowań base64 poza transmisją. Są to po prostu dwa typowe scenariusze, w których je zobaczysz.
Despertar,

1
Wyświetlisz skrót jako szesnastkowy, a nie dziesiętny. W przypadku skrótów jest to o wiele bardziej powszechne niż base64.
cHao

@ cHao Tak, jest to również powszechne. Cyfry szesnastkowe mogą reprezentować dowolne dane binarne, ale podstawa 64 ma tę zaletę, że zajmuje dużo mniej miejsca, ponieważ używa więcej znaków.
Despertar

45

Wiele lat temu, kiedy wprowadzono funkcję mailingową, która w miarę upływu czasu była całkowicie oparta na tekście, pojawiła się potrzeba załączników takich jak obraz i media (audio, wideo itp.). Gdy te załączniki są wysyłane przez Internet (który zasadniczo ma postać danych binarnych), prawdopodobieństwo uszkodzenia danych binarnych jest wysokie w surowej postaci. Aby rozwiązać ten problem, pojawił się BASE64.

Problem z danymi binarnymi polega na tym, że zawiera znaki zerowe, które w niektórych językach, takich jak C, C ++, reprezentują ciąg znaków końca łańcucha, więc wysyłanie danych binarnych w postaci surowej zawierającej bajty NULL uniemożliwi pełne odczytanie pliku i doprowadzi do uszkodzenia danych.

Na przykład :

W językach C i C ++ ten znak „null” pokazuje koniec łańcucha. „HELLO” jest więc przechowywane w następujący sposób:

WITAJ

72 69 76 76 79 00

00 mówi „zatrzymaj się tutaj”.

Zobaczmy teraz, jak działa kodowanie BASE64.

Punkt, na który należy zwrócić uwagę: długość łańcucha powinna być wielokrotnością 3.

Przykład 1 :

Łańcuch do zakodowania: „as”, długość = 3

1) Konwertuj każdy znak na dziesiętny.

a = 97, c = 99, e = 101

wprowadź opis zdjęcia tutaj

2) Zmień każdą dziesiętną na 8-bitową reprezentację binarną.

97 = 01100001, 99 = 01100011, 101 = 01100101

Łącznie: 01100001 01100011 01100101

3) Rozdziel na grupy 6-bitowe.

011000 010110 001101 100101

4) Oblicz binarne na dziesiętne

011000 = 24, 010110 = 22, 001101 = 13, 100101 = 37

5) Ukryte znaki dziesiętne do base64 przy użyciu wykresu base64.

24 = Y, 22 = W, 13 = N, 37 = l

„Ace” => „YWNl”

wprowadź opis zdjęcia tutaj

Przykład 2:

Łańcuch do zakodowania: „abcd” Długość = 4, nie jest wielokrotnością 3. Aby więc łańcuch był wielokrotnością 3, musimy dodać 2-bitowe wypełnienie, aby uzyskać długość = 6. Bit wypełnienia jest reprezentowany przez znak „=”.

Punkt, na który należy zwrócić uwagę: jeden bit dopełniający równa się dwóm zerom 00, więc dwa bit dopełniający równa się 4 zerom 0000.

Zacznijmy więc proces:

1) Konwertuj każdy znak na dziesiętny.

a = 97, b = 98, c = 99, d = 100

2) Zmień każdą dziesiętną na 8-bitową reprezentację binarną.

97 = 01100001, 98 = 01100010, 99 = 01100011, 100 = 01100100

3) Oddziel w grupie 6 bitów.

011000, 010110, 001001, 100011, 011001, 00

więc ostatni 6-bit nie jest kompletny, więc wstawiamy dwa bity wypełniające, które są równe czterem zerom „0000”.

011000, 010110, 001001, 100011, 011001, 000000 ==

Teraz jest równy. Dwa znaki równości na końcu pokazują, że dodano 4 zera (pomaga w dekodowaniu).

4) Oblicz binarne na dziesiętne.

011000 = 24, 010110 = 22, 001001 = 9, 100011 = 35, 011001 = 25, 000000 = 0 ==

5) Ukryte znaki dziesiętne do base64 przy użyciu wykresu base64.

24 = Y, 22 = W, 9 = j, 35 = j, 25 = Z, 0 = A ==

„Abcd” => „YWJjZA ==”


5
to naprawdę świetne wytłumaczenie
maheshmnj

28

We wczesnych czasach komputerów, gdy komunikacja między systemami nie była szczególnie niezawodna, zastosowano szybką i brudną metodę weryfikacji integralności danych: „parzystość bitów”. W tej metodzie każdy przesyłany bajt miałby 7 bitów danych, a ósmy to 1 lub 0, aby wymusić, aby całkowita liczba 1 bitów była parzysta.

Stąd 0x01 byłby transmitowany jako 0x81; 0x02 to 0x82; 0x03 pozostanie 0x03 itd.

Aby rozwinąć ten system, gdy zdefiniowano zestaw znaków ASCII, tylko 00-7F przypisano znaki. (Do dziś wszystkie znaki ustawione w zakresie 80-FF są niestandardowe)

Wielu routerów tego dnia umieszcza sprawdzanie parzystości i translację bajtów na sprzęcie, zmuszając podłączone do nich komputery do ścisłego radzenia sobie z 7-bitowymi danymi. Wymusza to konwersję załączników wiadomości e-mail (i wszystkich innych danych, dlatego protokoły HTTP i SMTP są oparte na tekście) do konwersji na format tekstowy.

Niewiele routerów przetrwało w latach 90. Poważnie wątpię, aby którykolwiek z nich był dzisiaj używany.


2
To doskonały punkt do dyskusji i ciekawa lekcja historii, dzięki.
Dan Bechard

26

Od http://en.wikipedia.org/wiki/Base64

Termin Base64 odnosi się do konkretnego kodowania przesyłania treści MIME. Jest również używany jako ogólny termin dla każdego podobnego schematu kodowania, który koduje dane binarne, traktując je liczbowo i tłumacząc je na podstawową reprezentację 64. Konkretny wybór bazy wynika z historii kodowania zestawu znaków: można wybrać zestaw 64 znaków, który jest częścią podzbioru wspólnego dla większości kodowań, a także do wydruku. Ta kombinacja pozostawia mało prawdopodobne modyfikowanie danych podczas przesyłania przez systemy, takie jak poczta e-mail, które tradycyjnie nie były 8-bitowe.

Base64 może być używany w różnych kontekstach:

  • Evolution i Thunderbird używają Base64 do zaciemniania haseł e-mail [1]
  • Base64 może służyć do przesyłania i przechowywania tekstu, który w przeciwnym razie może spowodować kolizję separatora
  • Base64 jest często używany jako szybki, ale niepewny skrót do ukrywania tajemnic bez ponoszenia nakładów związanych z zarządzaniem kluczami kryptograficznymi

  • Spamerzy używają Base64, aby uniknąć podstawowych narzędzi antyspamowych, które często nie dekodują Base64, a zatem nie mogą wykryć słów kluczowych w zakodowanych wiadomościach.

  • Base64 służy do kodowania ciągów znaków w plikach LDIF
  • Base64 jest czasem używany do osadzania danych binarnych w pliku XML przy użyciu składni podobnej do ...... np. Firefox's bookmarks.html.
  • Base64 jest również używany podczas komunikacji z rządowymi urządzeniami drukującymi podpisy podatkowe (zwykle przez porty szeregowe lub równoległe), aby zminimalizować opóźnienie przy przesyłaniu znaków potwierdzenia do podpisania.
  • Base64 służy do kodowania plików binarnych, takich jak obrazy w skryptach, aby uniknąć w zależności od plików zewnętrznych.
  • Można go użyć do osadzenia surowych danych obrazu we właściwości CSS, takiej jak obraz w tle.

11

Niektóre protokoły transportowe umożliwiają przesyłanie tylko znaków alfanumerycznych. Wyobraź sobie sytuację, w której znaki sterujące są używane do uruchamiania specjalnych akcji i / lub obsługują tylko ograniczoną szerokość bitów na znak. Base64 przekształca wszelkie dane wejściowe w kodowanie, które wykorzystuje tylko znaki alfanumeryczne +, /oraz =jako znak dopełniający.


8

Wykorzystanie Base64, które zamierzam tutaj opisać, jest nieco włamaniem. Więc jeśli nie lubisz hacków, nie kontynuuj.

Wpadłem w kłopoty, gdy odkryłem, że utf8 MySQL nie obsługuje 4-bajtowych znaków Unicode, ponieważ używa 3-bajtowej wersji utf8. Co więc zrobiłem, aby obsłużyć pełny 4-bajtowy kod Unicode nad utf8 MySQL? Cóż, base64 koduje ciągi podczas przechowywania w bazie danych, a base64 dekoduje podczas pobierania.

Ponieważ kodowanie i dekodowanie base64 jest bardzo szybkie, powyższe działało idealnie.

Należy wziąć pod uwagę następujące punkty:

  • Kodowanie Base64 zużywa o 33% więcej pamięci

  • Ciągi przechowywane w bazie danych nie będą czytelne dla ludzi (można to sprzedać jako funkcję, że ciągi bazy danych używają podstawowej formy szyfrowania).

Możesz użyć powyższej metody dla dowolnego silnika pamięci, który nie obsługuje Unicode.


6
„Możesz to sprzedać jako funkcję, że ciągi bazy danych używają podstawowej formy szyfrowania” Podoba mi się twój styl: D
Ercan

7
„Można to sprzedać jako funkcję polegającą na tym, że ciągi bazy danych używają podstawowej formy szyfrowania”. Co za okropna rzecz powiedzieć: D
Alex

1
podstawowa forma szyfrowania przed każdym, kto nie ma algorytmu dekodowania base64 rofl: D
Eladian

1
@Alex W ogóle nie jest to „okropna rzecz do powiedzenia”. Dane wrażliwe drugiego stopnia mogą być kodowane w standardzie base64, aby uniemożliwić ich odczytanie przez administratorów db. Nie zawsze konieczny jest najwyższy poziom szyfrowania dla każdej części danych. Na przykład, jeśli chcesz ukryć „komentarze” przed administratorem db, to base64 jest odpowiednie dla zadania. Gratcias!
Basil Musa

1
Warto wspomnieć, że MySQL obsługuje teraz wszystkie Unicode, chociaż dla celów kompatybilności wstecznej ich utf8typ jest nadal tylko trzy bajty; jeśli chcesz prawdziwą rzecz, użyj utf8mb4. Niezły hack, ale nie jest już potrzebny.
TRiG,

7

Służy do konwersji dowolnych danych binarnych na tekst ASCII.

Na przykład załączniki e-mail są wysyłane w ten sposób.


7

Używam go w sensie praktycznym, gdy przesyłamy duże obiekty binarne (obrazy) za pośrednictwem usług internetowych. Więc kiedy testuję usługę C # przy użyciu skryptu python, obiekt binarny można odtworzyć z odrobiną magii.

[W python]

import base64
imageAsBytes = base64.b64decode( dataFromWS )

1
Czy dane przesyłane są szybciej?
FelipeM,

6

„Schematy kodowania Base64 są powszechnie stosowane, gdy zachodzi potrzeba kodowania danych binarnych, które muszą być przechowywane i przesyłane na nośnikach zaprojektowanych do obsługi danych tekstowych. Ma to zapewnić, że dane pozostaną nienaruszone bez modyfikacji podczas transportu ”(Wiki, 2017)

Przykład może wyglądać następująco: masz usługę internetową, która akceptuje tylko znaki ASCII. Chcesz zapisać, a następnie przenieść dane użytkownika do innej lokalizacji (API), ale odbiorca chce otrzymywać nietknięte dane. Do tego służy Base64. . . Jedynym minusem jest to, że kodowanie base64 będzie wymagało około 33% więcej miejsca niż zwykłe ciągi.

Kolejny przykład :: uenc = url encoded = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.querytip.com/asics-men-s-gii-y-ml.yxml .

Jak widać, nie możemy wstawić char „/” w adresie URL, jeśli chcemy wysłać ostatnio odwiedzany adres URL jako parametr, ponieważ złamalibyśmy regułę atrybutu / wartości dla „MOD przepisywania” - parametru GET.

Pełny przykład to: „ http://loc.querytip.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product / 93 /


4

Przeważnie widziałem, jak to było używane do kodowania danych binarnych w kontekstach, które mogą obsługiwać tylko ascii - lub proste - zestawy znaków.


3

Aby rozwinąć nieco to, co mówi Brad: wiele mechanizmów transportu poczty e-mail i Usenetu oraz inne sposoby przenoszenia danych nie są „8-bitowe czyste”, co oznacza, że ​​znaki spoza standardowego zestawu znaków ascii mogą być zniekształcone podczas transportu - na przykład 0x0D może być postrzegane jako znak powrotu karetki i zamieniony w znak powrotu karetki i znak wiersza. Baza 64 odwzorowuje wszystkie znaki binarne na kilka standardowych liter i cyfr ascii oraz interpunkcji, aby nie zostały w ten sposób zniekształcone.


2

Base64

Base64 to ogólny termin na wiele podobnych schematów kodowania, które kodują dane binarne, traktując je liczbowo i tłumacząc je na reprezentację base 64. Termin Base64 pochodzi z określonego kodowania przesyłania treści MIME.

Schematy kodowania Base64 są powszechnie stosowane, gdy zachodzi potrzeba kodowania danych binarnych, które muszą być przechowywane i przesyłane za pośrednictwem mediów zaprojektowanych do obsługi danych tekstowych. Ma to zapewnić, że dane pozostaną nienaruszone bez modyfikacji podczas transportu. Base64 jest powszechnie używany w wielu aplikacjach, w tym w e-mailach przez MIME i do przechowywania złożonych danych w formacie XML.


0

Base64 może być wykorzystywany do wielu celów.

Głównym powodem jest konwersja danych binarnych na coś przejezdnego.

Czasami używam go do przesyłania danych JSON z jednej witryny do drugiej, przechowywania informacji o użytkowniku w plikach cookie.

Uwaga: „Możesz” używać go do szyfrowania - nie rozumiem, dlaczego ludzie twierdzą, że nie możesz i że nie jest to szyfrowanie, chociaż można je łatwo złamać i jest niezadowolone. Szyfrowanie oznacza nic więcej niż konwersję jednego ciągu danych na inny ciąg danych, które można później odszyfrować lub nie, i tak właśnie działa base64.



2
Jesteś interpretacji definicji „szyfrowania” zdecydowanie zbyt dosłownie. Słowo ewoluowało w coś nieco bardziej konkretnego niż jego pochodzenie.
Dan Bechard

0

Jedna cyfra szesnastkowa składa się z jednego skubka (4 bity). Dwie skubki tworzą 8 bitów, które są również nazywane 1 bajtem.

MD5 generuje wyjście 128-bitowe, które jest reprezentowane za pomocą sekwencji 32 cyfr szesnastkowych, które z kolei mają 32 * 4 = 128 bitów. 128 bitów tworzy 16 bajtów (ponieważ 1 bajt to 8 bitów).

Każdy znak Base64 koduje 6 bitów (z wyjątkiem ostatniego znaku niebędącego padem, który może kodować 2, 4 lub 6 bitów, oraz końcowe znaki pada, jeśli występują). Dlatego, zgodnie z kodowaniem Base64, 128-bitowy skrót wymaga co najmniej ⌈128 / 6⌉ = 22 znaków, plus pad, jeśli występuje.

Za pomocą base64 możemy wyprodukować zakodowane wyjście o pożądanej długości (6, 8 lub 10). Jeśli zdecydujemy się na wyjście o długości 8 znaków, zajmuje ono tylko 8 bajtów, podczas gdy zajmowało 16 bajtów dla 128-bitowego wyniku mieszania.

Oprócz bezpieczeństwa kodowanie base64 służy również do zmniejszenia zajmowanego miejsca.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.