Dlaczego używamy Base64?

Wikipedia mówi

Schematy kodowania Base64 są powszechnie używane, gdy istnieje potrzeba kodowania danych binarnych, które muszą być przechowywane i przesyłane przez media, które są zaprojektowane do radzenia sobie z danymi tekstowymi. Ma to na celu zapewnienie, że dane pozostają nienaruszone bez modyfikacji podczas transportu.

Ale czy nie jest tak, że dane są zawsze przechowywane / przesyłane w postaci binarnej, ponieważ pamięć, którą mają nasze maszyny, przechowuje dane binarne i to zależy tylko od tego, jak je zinterpretujesz? Tak więc, niezależnie od tego, czy kodujesz wzorzec bitowy 010011010110000101101110 jako Man W ASCII, czy jako TWFu W Base64, ostatecznie zachowasz ten sam wzorzec bitowy.

Jeśli ostateczne kodowanie jest w kategoriach zer i jedynek, a każda maszyna i media mogą sobie z nimi poradzić, jakie ma znaczenie, czy dane są reprezentowane jako ASCII lub Base64?

Co to znaczy "media, które są zaprojektowane do obsługi danych tekstowych"? Mogą radzić sobie z binarnymi = > mogą radzić sobie ze wszystkim.


Dzięki wszyscy, myślę, że teraz rozumiem.

Kiedy wysyłamy dane, nie możemy być pewni, że dane zostaną zinterpretowane w tym samym formacie, w jakim zamierzaliśmy je mieć. Wysyłamy więc dane zakodowane w jakimś formacie (takim jak Base64), który obie strony rozumieją. W ten sposób, nawet jeśli nadawca i odbiorca interpretują te same rzeczy inaczej, ale ponieważ zgadzają się co do zakodowanego formatu, DANE nie zostaną źle zinterpretowane.

From Mark Byers example

Jeśli chcę wysłać

Hello
world!

Jednym ze sposobów jest wysłanie go w ASCII jak

72 101 108 108 111 10 119 111 114 108 100 33

Ale bajt 10 może nie być poprawnie interpretowany jako znak nowej linii na drugim końcu. Tak więc, używamy podzbioru ASCII, aby zakodować go w ten sposób

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

, który kosztem większej ilości danych przesłanych dla tej samej ilości informacji zapewnia, że odbiornik może dekodować dane w zamierzony sposób, nawet jeśli odbiornik ma różne interpretacje dla reszty zestawu znaków.

Author: mega6382, 2010-08-21

12 answers

Twoim pierwszym błędem jest myślenie, że kodowanie ASCII i kodowanie Base64 są wymienne. Nie są. Są one wykorzystywane do różnych celów.

  • gdy kodujesz tekst w ASCII, zaczynasz od ciągu tekstowego i konwertujesz go na sekwencję bajtów.
  • gdy kodujesz dane w Base64, zaczynasz od sekwencji bajtów i konwertujesz je na ciąg tekstowy.

Aby zrozumieć, dlaczego Base64 był potrzebny w pierwszej kolejności potrzebujemy trochę historii Informatyka.


Komputery komunikują się w binarnych-0s i 1s - ale ludzie zazwyczaj chcą komunikować się z bardziej bogatych danych formularzy, takich jak tekst lub obrazy. Aby przesłać te dane między komputerami, najpierw należy je zakodować do 0s i 1s, przesłać, a następnie ponownie rozkodować. Przykładem może być tekst - istnieje wiele różnych sposobów na wykonanie tego kodowania. Byłoby o wiele prościej, gdybyśmy wszyscy mogli uzgodnić jedno kodowanie, ale niestety tak nie jest.

Oryginalnie dużo kod Baudota), który używał innej liczby bitów na znak, aż ostatecznie ASCII stał 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 wymazałyby nawet najbardziej znaczący bit. Ponadto różnica w kodowaniu kończącym linię w różnych systemach oznacza, że znak ASCII 10 i 13 były również czasami modyfikowane.

Aby rozwiązać te problemy wprowadzono kodowanie Base64. Pozwala to na kodowanie bajtów aribtrary do bajtów, które są znane jako Bezpieczne do wysłania bez uszkodzenia (znaki alfanumeryczne ASCII i kilka symboli). Wadą jest to, że kodowanie wiadomości za pomocą Base64 zwiększa jej długość - co 3 bajty danych kodowane są do 4 znaków ASCII.

Aby wysłać tekst można najpierw zakodować do bajtów za pomocą UTF-8), a następnie Base64 zakoduje wynikowe dane binarne w łańcuch tekstowy, który można bezpiecznie wysłać zakodowany jako ASCII. Odbiorca będzie musiał odwrócić ten proces, aby odzyskać oryginalną wiadomość. Wymaga to oczywiście, aby odbiornik wiedział, które kodowania zostały użyte, a informacje te często muszą być wysyłane osobno.

Historycznie był używany do kodowania danych binarnych w wiadomościach e-mail, gdzie serwer pocztowy 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 znaki takie jak ' ' nie były interpretowane jako znaczniki.


Oto przykład pracy:

Chcę wysłać wiadomość tekstową z dwoma linijkami

Hello
world!

Jeśli wyślę go jako ASCII (lub UTF-8) będzie wyglądał tak:

72 101 108 108 111 10 119 111 114 108 100 33

Bajt 10 jest uszkodzony w niektórych systemach, więc możemy oprzeć 64 kodowanie tych bajtów jako łańcuch Base64:

SGVsbG8sCndvcmxkIQ==

Które po zakodowaniu za pomocą ASCII wygląda tak:

83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61

Wszystkie bajty tutaj są znane jako Bezpieczne bajty, więc jest bardzo mała szansa, że jakikolwiek system uszkodzi tę wiadomość. Mogę wysłać tę wiadomość zamiast oryginalnej wiadomości i pozwolić odbiorcy odwrócić proces, aby odzyskać oryginalną wiadomość.

 201
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 18:02:29

Kodowanie danych binarnych w XML

Załóżmy, że chcesz osadzić kilka obrazów w dokumencie XML. Obrazy są danymi binarnymi, podczas gdy dokument XML jest tekstowy. Ale XML nie może obsługiwać osadzonych danych binarnych. Więc jak to robisz?

Jedną z opcji jest kodowanie obrazów w base64, zamieniając dane binarne w tekst, który może obsługiwać XML.

Zamiast:

<images>
  <image name="Sally">{binary gibberish that breaks XML parsers}</image>
  <image name="Bobby">{binary gibberish that breaks XML parsers}</image>
</images>

Robisz:

<images>
  <image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
  <image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
</images>

I parser XML będzie mógł analizować dokument XML poprawnie i wyodrębnij dane obrazu.

 39
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 21:24:13

Dlaczego nie spojrzeć na RFC, które obecnie definiuje Base64?

Kodowanie bazowe danych jest używane w wiele sytuacji do przechowywania lub przenoszenia
danych w środowiskach, które być może dla przyczyny dziedziczenia, są ograniczone do US-ASCII [1] Dane.Kodowanie bazowe może może być również stosowany w nowych aplikacjach które nie mają ograniczeń dziedziczenia, po prostu dlatego, że umożliwia manipulowanie obiektami za pomocą tekstu redaktorów.

W przeszłości różne zastosowania mieć miał różne wymagania i w ten sposób czasami zaimplementowana baza kodowanie w nieco innym sposoby. Obecnie specyfikacje protokołu czasami stosuje się kodowanie bazowe w Ogólne, a w szczególności" base64", bez dokładnego opisu lub Referencja. Wielozadaniowa Poczta Internetowa Extensions (MIME) [4] jest często używany jako odniesienie do base64 bez biorąc pod uwagę konsekwencje dla zawijanie linii lub bez alfabetu postaci. Celem tego specyfikacja ma na celu ustalenie często alfabet i kodowanie rozważania. Mam nadzieję, że będzie to zmniejszyć niejednoznaczność w innych dokumentów, co prowadzi do lepszego interoperacyjność.

Base64 został pierwotnie opracowany jako sposób, aby umożliwić dołączanie danych binarnych do wiadomości e-mail jako część wielozadaniowych rozszerzeń poczty internetowej.

 31
Author: Billy ONeal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 15:39:00

Media, które są przeznaczone do danych tekstowych, są oczywiście również binarne, ale media tekstowe często używają pewnych wartości binarnych dla znaków sterujących. Ponadto Media tekstowe mogą odrzucać pewne wartości binarne jako nie-tekstowe.

Kodowanie Base64 koduje dane binarne jako wartości, które mogą być interpretowane tylko jako tekst w nośnikach tekstowych i jest wolne od znaków specjalnych i / lub znaków sterujących, dzięki czemu dane będą przechowywane również na nośnikach tekstowych.

 21
Author: Håvard S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 15:25:22

Chodzi bardziej o to, że nośnik waliduje kodowanie łańcuchów znaków, więc chcemy upewnić się, że dane są akceptowalne 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ść może nie wyświetlać się poprawnie, jeśli strumień jedynek i zer tworzy sekwencję , która nie jest poprawna w kodowaniu UTF-8.

Ten sam typ rzeczy dzieje się w Urlach, gdy chcemy zakodować znaki nie poprawne dla adresu URL w samym adresie URL:

Http://www.foo.com/hello mój przyjaciel - > http://www.foo.com/hello%20my%20friend

To dlatego, że chcemy wysłać przestrzeń nad systemem, który pomyśli, że przestrzeń jest śmierdząca.

Wszystko, co robimy, to upewnianie się, że istnieje odwzorowanie 1-do-1 między znaną dobrą, akceptowalną i nieszkodliwą sekwencją bitów do innej dosłownej sekwencji bitów i że obsługa aplikacja nie rozróżnia kodowania.

W twoim przykładzie, man może być poprawne ASCII w pierwszej formie; ale często możesz chcieć przesłać wartości, które są losowe binarne (np. wysyłając obraz w wiadomości e-mail):

MIME-Wersja: 1.0
Content-Description: "Base64 koduje a.gif"
Content-Type: image / gif; name="a.gif"
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename="a.gif"

Tutaj widzimy, że obraz GIF jest zakodowany w base64 jako fragment 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że być interpretowane jako protokół i unikamy wstawiania danych, które SMTP lub POP mogą uznać za znaczące.

 15
Author: Aiden Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 15:35:07

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 parser SAX, ponieważ dane te mogły być dosłownie wszystkim, w tym znakami specjalnymi XML. Base64 kodowanie danych na końcu nadawczym i dekodowanie ich na końcu odbiorczym rozwiązało ten problem.

 11
Author: Bill the Lizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:37

Większość komputerów przechowuje dane w 8-bitowym formacie binarnym, ale nie jest to wymagane. Niektóre Maszyny i media transmisyjne mogą obsługiwać tylko 7 bitów (a może nawet mniej) na raz. Taki nośnik zinterpretowałby strumień w wielokrotnościach 7 bitów, więc jeśli miałbyś wysłać 8-bitowe dane, nie otrzymasz tego, czego oczekujesz po drugiej stronie. Base-64 to tylko jeden ze sposobów na rozwiązanie tego problemu: kodujesz wejście do formatu 6-bitowego, wysyłasz je przez nośnik i dekodujesz z powrotem do formatu 8-bitowego w koniec odbioru.

 8
Author: casablanca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 15:32:17

Base64 zamiast znaków specjalnych

Dam ci zupełnie inny, ale prawdziwy przykład: piszę kod javascript, który ma być uruchamiany w przeglądarce. Znaczniki HTML mają wartości ID, ale istnieją ograniczenia co do tego, jakie znaki są ważne w identyfikatorze.

Ale chcę, aby mój identyfikator bezstratnie odnosił się do plików w moim systemie plików. Pliki w rzeczywistości może mieć wszelkiego rodzaju dziwne i wspaniałe znaki w nich z wykrzykników, znaki akcentowane, tyldy, nawet emoji! Nie mogę tego zrobić. to:

<div id="/path/to/my_strangely_named_file!@().jpg">
    <img src="http://myserver.com/path/to/my_strangely_named_file!@().jpg">
    Here's a pic I took in Moscow.
</div>

Załóżmy, że chcę uruchomić jakiś kod w ten sposób:

# ERROR
document.getElementById("/path/to/my_strangely_named_file!@().jpg");

Myślę, że ten kod nie powiedzie się po wykonaniu.

Z Base64 mogę odnosić się do czegoś skomplikowanego bez martwienia się o to, który język pozwala jakie znaki specjalne i które wymagają ucieczki: {]}

document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");

W przeciwieństwie do użycia MD5 lub innej funkcji mieszającej, możesz odwrócić kodowanie, aby dowiedzieć się, jakie dokładnie dane były przydatne.

Chciałbym wiedzieć o Base64 lata temu. Ja bym unikałem wyrywania włosów z "encodeURIComponent " i str.replace(‘\n’,’\\n’)
 6
Author: Sridhar-Sarnobat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 06:19:58

Co to znaczy " media, które są zaprojektowany do radzenia sobie z danymi tekstowymi"?

Że te protokoły zostały zaprojektowane do obsługi tekstu (często tylko Angielski tekst) zamiast danych binarnych (jak .png i .obrazy jpg).

Mogą radzić sobie z binarnymi = > mogą zajmij się wszystkim.

/ Align = "left" / Protokół Zaprojektowany do reprezentowania tekstu może niewłaściwie traktować dane binarne, które zawierają:
  • bajty 0x0A i 0x0D, używane dla zakończeń linii, które różnią się w zależności od platformy.
  • inne znaki sterujące, takie jak 0x00( null = C string terminator), 0x03 (koniec tekstu), 0x04 (koniec transmisji) lub 0X1A (DOS end-of-file), które mogą przedwcześnie sygnalizować koniec danych.
  • bajtów powyżej 0x7F (jeśli protokół został zaprojektowany dla ASCII).
  • sekwencje bajtów, które są niepoprawne UTF-8.

Więc nie możesz po prostu wysyłać danych binarnych przez protokół tekstowy. Jesteś ograniczony do bajtów które reprezentują znaki ASCII nie będące spacjami, których jest 94. Powodem, dla którego wybrano Base 64, było to, że szybsza jest praca z mocami dwójki, a 64 jest największą, która działa.

Jedno pytanie. Jak to jest? systemy nadal nie zgadzają się na wspólne technika kodowania jak w tak powszechnym UTF-8?

W Sieci, przynajmniej, w większości mają. Większość stron używa UTF-8.

Problem na Zachodzie polega na tym, że istnieje wiele starych programów, które mają 1 bajt = 1 znak i nie mogą pracować z UTF-8.

Problemem na Wschodzie jest ich przywiązanie do kodowania, takiego jak GB2312 i Shift_JIS.

I fakt, że Microsoft wydaje się nadal nie przeboleć, że wybrał złe kodowanie UTF. Jeśli chcesz korzystać z interfejsu Windows API lub biblioteki Microsoft C runtime, ograniczasz się do kodowania UTF-16 lub kodowania "ANSI" w języku lokalnym. To sprawia, że używanie UTF-8 jest bolesne, ponieważ trzeba przekonwertować wszystkie czas.

 4
Author: dan04,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 18:24:34

Oprócz innych (nieco długich) odpowiedzi: nawet ignorując stare systemy, które obsługują tylko 7-bitowe ASCII, podstawowe problemy z dostarczaniem danych binarnych w trybie tekstowym to:

  • nowe linie są zwykle przekształcane w trybie tekstowym.
  • Należy uważać, aby nie traktować bajtu NUL jako końca ciągu tekstowego, co jest zbyt łatwe do zrobienia w każdym programie z linią C.
 3
Author: jamesdlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 17:27:58

Co to znaczy "media, które są zaprojektowane do obsługi danych tekstowych"?

W czasach, gdy ASCII rządziło światem, radzenie sobie z wartościami nie-ASCII było bólem głowy. Ludzie przeskakiwali przez różnego rodzaju obręcze, aby je przenieść przez przewód, nie tracąc informacji.

 2
Author: dirkgently,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-21 15:24:34

Dlaczego/ jak używamy kodowania Base64?

Base64 jest jednym ze schematów kodowania binary-to-text o wydajności 75%. Jest on używany tak, aby typowe dane binarne (takie jak obrazy) mogły być bezpiecznie przesyłane przez starsze "nie czyste 8-bitowe" kanały. We wcześniejszych sieciach e-mail (do początku lat 90.) większość wiadomości e-mail była zwykłym tekstem 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". Efektywność systemu to stosunek pomiędzy liczbą bitów na wejściu a liczbą 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):

  1. dane binarne są ułożone w ciągłych kawałkach po 24 bity (3 bajty) każdy.
  2. Każdy 24-bitowy fragment jest pogrupowany w cztery części po 6 bitów każda.
  3. każda 6-bitowa grupa jest konwertowana na odpowiednie wartości znaków Base64, tj. kodowanie Base64 konwertuje trzy oktety na cztery zakodowane znaki. Stosunek bajtów wyjściowych do bajtów wejściowych wynosi 4: 3 (33% narzutu).
  4. Co ciekawe, te same znaki będą kodowane w różny sposób w zależności od ich pozycji w grupie trzech oktetów, która jest kodowana w celu wytworzenia czterech znaków.
  5. odbiorca będzie musiał odwrócić ten proces, aby odzyskać oryginalną wiadomość.
 1
Author: Mushtaq Hussain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 19:01:16