Wikipedia mówi
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.
Ale czy nie chodzi o to, że dane są zawsze przechowywane / przesyłane w formie binarnej, ponieważ pamięć, którą przechowują nasze maszyny, zależy tylko od tego, jak je interpretujesz? Tak więc, niezależnie od tego, czy kodujesz wzór bitowy 010011010110000101101110
jak Man
w ASCII czy jak TWFu
w Base64, ostatecznie zapiszesz ten sam wzór bitowy.
Jeśli ostateczne kodowanie jest w postaci zer i jedynek, a każda maszyna i nośnik może sobie z nimi poradzić, jak ważne jest, czy dane są reprezentowane jako ASCII czy Base64?
Co to znaczy „media przeznaczone do obsługi danych tekstowych”? Potrafią poradzić sobie z plikiem binarnym => poradzą sobie ze wszystkim.
Dzięki wszystkim, myślę, że teraz rozumiem.
Kiedy przesyłamy dane, nie możemy być pewni, że dane będą interpretowane w takim samym formacie, jaki zamierzaliśmy. Wysyłamy więc dane zakodowane w jakimś formacie (np. Base64), który obie strony rozumieją. W ten sposób nawet jeśli nadawca i odbiorca interpretują to samo inaczej, ale ponieważ zgadzają się co do formatu kodowanego, dane nie zostaną źle zinterpretowane.
Jeśli chcę wysłać
Hello
world!
Jednym ze sposobów jest wysłanie go w formacie ASCII
72 101 108 108 111 10 119 111 114 108 100 33
Ale bajt 10 może nie być poprawnie interpretowany jako nowy wiersz na drugim końcu. Tak więc używamy podzbioru ASCII do kodowania go w ten sposób
83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61
co kosztem większej ilości danych przesłanych dla tej samej ilości informacji zapewnia odbiorcy możliwość dekodowania danych w zamierzony sposób, nawet jeśli odbiorca zdarzy się mieć różne interpretacje dla reszty zestawu znaków.
Odpowiedzi:
Twoim pierwszym błędem jest myślenie, że kodowanie ASCII i kodowanie Base64 są wymienne. Oni nie są. Są wykorzystywane do różnych celów.
Aby zrozumieć, dlaczego Base64 był niezbędny, potrzebujemy trochę historii komputerów.
Komputery komunikują się w trybie binarnym - 0 i 1 - ale ludzie zazwyczaj chcą komunikować się z bardziej bogatymi formularzami danych, takimi jak tekst lub obrazy. Aby przesłać te dane między komputerami, najpierw należy je zakodować na 0 i 1, wysłać, a następnie ponownie zdekodować. Weźmy jako przykład tekst - istnieje wiele różnych sposobów wykonania tego kodowania. Byłoby o wiele łatwiej, gdybyśmy wszyscy zgodzili się na jedno kodowanie, ale niestety tak nie jest.
Początkowo utworzono wiele różnych kodowań (np. Kod Baudot ), które wykorzystywały inną liczbę bitów na znak, aż w końcu ASCII stało się standardem z 7 bitami na znak. Jednak większość komputerów przechowuje dane binarne w bajtach składających się z 8 bitów każdy, więc ASCII nie nadaje się do przesyłania tego typu danych. Niektóre systemy wyczyściłyby nawet najbardziej znaczący bit. Ponadto różnica w kodowaniu zakończeń linii w różnych systemach oznacza, że znaki ASCII 10 i 13 były również czasami modyfikowane.
Aby rozwiązać te problemy, wprowadzono kodowanie Base64 . Pozwala to zakodować bajty aribtrary do bajtów, o których wiadomo, że można je bezpiecznie przesyłać bez uszkodzenia (znaki alfanumeryczne ASCII i kilka symboli). Wadą jest to, że kodowanie wiadomości przy użyciu Base64 zwiększa jej długość - każde 3 bajty danych jest kodowane do 4 znaków ASCII.
Aby wysłać tekst niezawodnie możesz najpierw zakodować do bajtów stosując kodowanie tekstu do wyboru (na przykład UTF-8) i następnie później Base64 zakodować wynikających danych binarnych na ciąg tekstowy, który jest bezpieczny, aby wysłać zakodowany jako ASCII. Odbiorca będzie musiał odwrócić ten proces, aby odzyskać pierwotną wiadomość. Wymaga to oczywiście, aby odbiorca wiedział, które kodowania zostały użyte, a informacje te często muszą być przesyłane osobno.
Historycznie był używany do kodowania danych binarnych w wiadomościach e-mail, w których serwer e-mail może modyfikować zakończenia linii. Bardziej nowoczesnym przykładem jest użycie kodowania Base64 do osadzania danych obrazu bezpośrednio w kodzie źródłowym HTML . W tym przypadku konieczne jest zakodowanie danych, aby uniknąć interpretowania znaków takich jak „<” i „>” jako znaczniki.
Oto działający przykład:
Chcę wysłać wiadomość tekstową z dwoma wierszami:
Jeśli wyślę go jako ASCII (lub UTF-8), będzie to wyglądać następująco:
Bajt 10 jest uszkodzony w niektórych systemach, więc możemy kodować 64 bajty w postaci ciągu Base64:
Które po zakodowaniu przy użyciu ASCII wygląda następująco:
Wszystkie bajty tutaj są znanymi bajtami bezpiecznymi, więc jest bardzo małe prawdopodobieństwo, że jakikolwiek system zepsuje ten komunikat. Mogę wysłać to zamiast oryginalnej wiadomości i pozwolić odbiorcy odwrócić proces odzyskiwania oryginalnej wiadomości.
źródło
Kodowanie danych binarnych w XML
Załóżmy, że chcesz osadzić kilka obrazów w dokumencie XML. Obrazy są danymi binarnymi, a dokument XML tekstem. Ale XML nie może obsłużyć osadzonych danych binarnych. Jak to robisz?
Jedną z opcji jest kodowanie obrazów w base64, zamieniając dane binarne na tekst, który XML może obsłużyć.
Zamiast:
ty robisz:
Analizator składni XML będzie mógł poprawnie przeanalizować dokument XML i wyodrębnić dane obrazu.
źródło
.mht
format Microsoft (plik HTML + obrazy w jednym pliku).Dlaczego nie spojrzeć na RFC, która obecnie definiuje Base64 ?
Base64 został pierwotnie opracowany jako sposób na dołączanie danych binarnych do wiadomości e-mail jako część Uniwersalnych rozszerzeń poczty internetowej.
źródło
Nośniki przeznaczone do danych tekstowych są oczywiście również binarne, ale nośniki tekstowe często używają pewnych wartości binarnych dla znaków kontrolnych. Ponadto nośniki tekstowe mogą odrzucać niektóre wartości binarne jako nietekstowe.
Kodowanie Base64 koduje dane binarne jako wartości, które mogą być interpretowane tylko jako tekst w mediach tekstowych i są wolne od jakichkolwiek znaków specjalnych i / lub znaków kontrolnych, dzięki czemu dane zostaną zachowane również w mediach tekstowych.
źródło
Chodzi o to, że media się sprawdzają kodowania łańcucha, dlatego chcemy upewnić się, że dane są akceptowane przez aplikację obsługującą (i nie zawierają sekwencji binarnej reprezentującej na przykład EOL)
Wyobraź sobie, że chcesz wysłać dane binarne w wiadomości e-mail z kodowaniem UTF-8 - Wiadomość e-mail może nie być wyświetlana poprawnie, jeśli strumień zer i jedynek utworzy sekwencję która nie jest prawidłowa w kodowaniu UTF-8.
Ten sam typ rzeczy dzieje się w adresach URL, gdy chcemy zakodować znaki niepoprawne dla adresu URL w samym adresie URL:
Jest tak, ponieważ chcemy wysłać przestrzeń przez system, który będzie myślał, że przestrzeń jest śmierdząca.
Wszystko, co robimy, to upewnienie się, że istnieje mapowanie 1 do 1 między znaną dobrą, akceptowalną i nieszkodliwą sekwencją bitów na inną dosłowną sekwencję bitów oraz że aplikacja obsługująca nie rozróżnia kodowania.
W twoim przykładzie
man
może być poprawny ASCII w pierwszej formie; ale często możesz chcieć przesyłać wartości losowo binarne (tj. wysyłając obraz w wiadomości e-mail):Widzimy tutaj, że obraz GIF jest zakodowany w base64 jako część wiadomości e-mail. Klient poczty e-mail odczytuje nagłówki i dekoduje je. Ze względu na kodowanie możemy być pewni, że GIF nie zawiera niczego, co można interpretować jako protokół, i unikamy wstawiania danych, które SMTP lub POP mogą uznać za znaczące.
źródło
Base64 zamiast ucieczki znaków specjalnych
Dam ci zupełnie inny, ale prawdziwy przykład: piszę kod javascript, aby uruchomić go w przeglądarce. Tagi HTML mają wartości identyfikatora, ale istnieją ograniczenia dotyczące tego, jakie znaki są prawidłowe w identyfikatorze.
Ale chcę, aby mój identyfikator bezstratnie odnosił się do plików w moim systemie plików. Pliki w rzeczywistości mogą zawierać przeróżne dziwne i cudowne postacie od wykrzykników, znaków akcentowanych, tyldy, a nawet emoji! Nie mogę tego zrobić:
Załóżmy, że chcę uruchomić taki kod:
Myślę, że ten kod zawiedzie po uruchomieniu.
Dzięki Base64 mogę odwoływać się do czegoś skomplikowanego, nie martwiąc się o to, który język zezwala na znaki specjalne, a które wymagają ucieczki:
W przeciwieństwie do korzystania z MD5 lub innej funkcji skrótu, możesz odwrócić kodowanie, aby dowiedzieć się, jakie dokładnie dane były faktycznie przydatne.
Chciałbym wiedzieć o Base64 lata temu. Unikałbym odrywania włosów za pomocą „
encodeURIComponent
” istr.replace(‘\n’,’\\n’)
Przesyłanie tekstu przez SSH:
Jeśli próbujesz przesyłać złożone dane przez ssh (np. Plik kropkowy, aby uzyskać personalizacje powłoki), powodzenia w tworzeniu bez bazy 64. W ten sposób możesz to zrobić z bazą 64 (wiem, że możesz użyć SCP, ale wymagałoby to wielu poleceń - co komplikuje powiązania klawiszy dla sshing na serwerze):
źródło
Jednym z przykładów, kiedy uznałem to za wygodne, była próba osadzenia danych binarnych w XML . Niektóre dane binarne były błędnie interpretowane przez analizator składni SAX, ponieważ mogły to być dosłownie wszystko, w tym znaki specjalne XML. Kodowanie Base64 danych po stronie nadawczej i dekodowanie po stronie odbiorczej rozwiązało ten problem.
źródło
Większość komputerów przechowuje dane w 8-bitowym formacie binarnym, ale nie jest to wymagane. Niektóre maszyny i media transmisyjne mogą jednocześnie obsługiwać tylko 7 bitów (a może nawet mniej). Takie medium interpretowałoby strumień jako wielokrotność 7 bitów, więc jeśli wyślesz 8-bitowe dane, nie otrzymasz tego, czego oczekujesz po drugiej stronie. Base-64 to tylko jeden ze sposobów rozwiązania tego problemu: kodujesz dane wejściowe w formacie 6-bitowym, wysyłasz je za pośrednictwem nośnika i dekodujesz z powrotem do formatu 8-bitowego na końcu odbierającym.
źródło
Oprócz innych (nieco długich) odpowiedzi: nawet ignorując stare systemy, które obsługują tylko 7-bitowy ASCII, podstawowe problemy z dostarczaniem danych binarnych w trybie tekstowym to:
źródło
Że te protokoły zostały zaprojektowane do obsługi tekstu (często tylko tekst angielski ) zamiast danych binarnych (takich jak obrazy .png i .jpg).
Ale odwrotność nie jest prawdą. Protokół zaprojektowany do reprezentowania tekstu może niewłaściwie traktować dane binarne, które zawierają:
Dlatego nie można po prostu wysyłać danych binarnych za pomocą protokołu tekstowego. Jesteś ograniczony do bajtów, które reprezentują niekontrolujące znaki ASCII niebędące spacjami, których jest 94. Powodem, dla którego wybrano Base 64, była szybsza praca z potęgami dwóch, a 64 jest największym działającym .
Przynajmniej w sieci mają je w większości. Większość stron używa UTF-8 .
Problem na Zachodzie polega na tym, że istnieje wiele starych programów, które zakładają, że 1 bajt = 1 znak i nie mogą współpracować z UTF-8.
Problemem na Wschodzie jest ich przywiązanie do kodowań takich jak GB2312 i Shift_JIS.
I fakt, że Microsoft wciąż nie przestawał wybierać niewłaściwego kodowania UTF. Jeśli chcesz korzystać z interfejsu API systemu Windows lub biblioteki wykonawczej Microsoft C, jesteś ograniczony do UTF-16 lub kodowania „ANSI” regionu. To sprawia, że korzystanie z UTF-8 jest bolesne, ponieważ musisz cały czas konwertować.
źródło
Dlaczego / Jak korzystamy z kodowania Base64?
Base64 jest jednym ze schematów kodowania binarnego na tekst o wydajności 75%. Służy do tego, aby typowe dane binarne (takie jak obrazy) mogły być bezpiecznie przesyłane starszymi kanałami „nie 8-bitowymi czystymi”. We wcześniejszych sieciach e-mail (do początku lat 90. XX wieku) większość wiadomości e-mail zawierała zwykły tekst w 7-bitowym zestawie znaków US-ASCII. Tak wiele wczesnych standardów protokołu komunikacyjnego zostało zaprojektowanych do pracy nad „7-bitowymi” łączami komunikacyjnymi, „a nie 8-bitowymi czystymi”. Wydajność schematu to stosunek liczby bitów na wejściu do liczby bitów na zakodowanym wyjściu. Szesnastkowy (Base16) jest również jednym ze schematów kodowania binarnego na tekst z wydajnością 50%.
Kroki kodowania Base64 (uproszczone):
źródło
W czasach, gdy ASCII rządził światem zajmującym się wartościami innymi niż ASCII, bolała mnie głowa. Ludzie przeskakiwali przez różnego rodzaju obręcze, aby przenieść je przez drut bez utraty informacji.
źródło