ToolDeck

Base64

7 narzędzi

Czym jest kodowanie?

Kodowanie to proces przekształcania danych z jednej reprezentacji na inną. W tworzeniu stron internetowych kodowanie służy do bezpiecznego przesyłania danych przez kanały zaprojektowane dla ograniczonego zestawu znaków — na przykład do wysyłania danych binarnych przez protokół tekstowy lub umieszczania znaków specjalnych w URL.

Kodowanie znaków określa, jak znaki tekstowe są odwzorowywane na bajty. Kodowanie Base64 przekształca dane binarne na tekst ASCII. Kodowanie URL sprawia, że dowolny tekst jest bezpieczny do użycia w adresach URL. Zrozumienie tych trzech warstw kodowania zapobiega subtelnym błędom i lukom bezpieczeństwa.

Historia kodowania znaków

Kodowanie znaków to odwzorowanie między znakami (literami, symbolami) a ich binarnymi reprezentacjami. Ewolucja od ASCII do Unicode odzwierciedla globalizację internetu:

ASCII1963
128 znaków

7-bitowy amerykański kod standardowy. 128 znaków: angielskie litery, cyfry, znaki interpunkcyjne i kody sterujące. Zdefiniował podstawowe kodowanie, na którym opierają się wszystkie inne.

Latin-11987
256 znaków

Rozszerzony ASCII dla języków Europy Zachodniej. Dodał 128 znaków (litery z akcentami, symbole). Nieodpowiedni dla pisma nielatyńskiego.

Unicode1991
149 186+ znaków

Uniwersalny zestaw znaków obejmujący wszystkie systemy pisma na świecie. Definiuje punkty kodowe dla ponad 149 000 znaków w 161 skryptach. Nie definiuje kodowania — to zadanie UTF-8/16/32.

UTF-81993
Cały Unicode znaków

Kodowanie o zmiennej szerokości używające 1–4 bajtów na znak. Kompatybilne z ASCII (pierwsze 128 punktów kodowych to pojedyncze bajty). Dominujące kodowanie w sieci — ponad 98% stron internetowych.

UTF-161996
Cały Unicode znaków

Kodowanie o zmiennej szerokości używające 2 lub 4 bajtów na znak. Stosowane wewnętrznie przez Windows, Java i ciągi znaków JavaScript. Niekompatybilne z ASCII.

UTF-322000
Cały Unicode znaków

Kodowanie o stałej szerokości: zawsze 4 bajty na znak. Proste, ale marnuje miejsce. Stosowane w niektórych wewnętrznych mechanizmach baz danych. Rzadko spotykane w sieci.

Dlaczego wygrało UTF-8

UTF-8 stało się dominujące, ponieważ jest wstecznie kompatybilne z ASCII (pierwsze 128 znaków koduje się identycznie), jest samosynchronizujące (granice znaków można znaleźć przez skanowanie) i efektywnie wykorzystuje miejsce dla tekstu łacińskiego. Każdy dokument ASCII jest prawidłowym dokumentem UTF-8. Dzięki temu migracja była bezproblemowa.

Kodowanie Base64

Base64 przekształca dane binarne na reprezentację tekstową, używając jedynie 64 drukowalnych znaków ASCII: A–Z, a–z, 0–9, + i /. Jest to konieczne, gdy dane binarne muszą przechodzić przez kanały obsługujące wyłącznie tekst — załączniki e-mail, data URI, tokeny JWT i HTTP Basic Auth — wszystkie korzystają z Base64.

Jak to działa

Base64 grupuje bajty wejściowe w 3-bajtowe (24-bitowe) bloki i koduje każdy blok jako 4 znaki Base64 (po 6 bitów każdy). Jeśli dane wejściowe nie są wielokrotnością 3 bajtów, dodawane są znaki dopełnienia =, aby uzupełnić ostatnią grupę:

WejścieBajty hexBase64
"Man"77 61 6ETWFu
"Ma"4D 61TWE=
"M"4DTQ==

Znaki dopełnienia = na końcu wskazują, ile bajtów brakowało do uzupełnienia ostatniej 3-bajtowej grupy. Jeden = oznacza, że potrzebny był jeden bajt dopełnienia; == oznacza, że potrzebne były dwa bajty. Standardowy Base64 zawsze generuje wynik, którego długość jest wielokrotnością 4.

Kodowanie URL

Adresy URL mogą zawierać tylko ograniczony zestaw bezpiecznych znaków ASCII. Każdy znak spoza tego zestawu — w tym spacje, znaki interpunkcyjne, znaki spoza ASCII oraz specjalne znaki URL takie jak &, = i # — musi zostać zakodowany procentowo (URL-encoded) przed umieszczeniem w adresie URL.

Kodowanie procentowe zastępuje każdy niebezpieczny bajt znakiem % po którym następują dwie cyfry szesnastkowe reprezentujące wartość tego bajtu. Spacja staje się %20, ampersand staje się %26 itd.

Często kodowane znaki

ZnakZakodowanyUwagi
Space%20Najczęstszy; używany w przesyłaniu formularzy jako + w application/x-www-form-urlencoded
&%26Separator ciągu zapytania; musi być zakodowany gdy używany jako wartość dosłowna
=%3DSeparator klucz-wartość w ciągach zapytania; koduj gdy używany jako dane
+%2BInterpretowany jako spacja w application/x-www-form-urlencoded; koduj, aby zachować dosłowny +
#%23Identyfikator fragmentu; koduj gdy używany jako dane dosłowne w ścieżce lub zapytaniu
/%2FSeparator segmentów ścieżki; koduj gdy używany jako dane dosłowne, nie jako ogranicznik ścieżki
:%3ASeparator schematu; koduj w kontekstach ścieżki i zapytania
@%40Używany w mailto: i uwierzytelnianiu; koduj gdy używany jako dane dosłowne

encodeURI vs encodeURIComponent

JavaScript udostępnia dwie funkcje kodowania o różnym zakresie. encodeURI koduje kompletny URL — pozostawia znaki mające znaczenie w URL-ach (:, /, ?, #, @) niezakodowane. encodeURIComponent koduje komponent URL (wartość pojedynczego parametru zapytania lub segment ścieżki) — koduje wszystkie znaki oprócz A-Z, a-z, 0-9, -, _, ., ~. Zawsze używaj encodeURIComponent dla pojedynczych wartości i encodeURI dla kompletnych URL-ów.

Gdzie kodowanie pojawia się w tworzeniu stron internetowych

Uwierzytelnianie HTTP Basic

Nagłówek Authorization: Basic koduje dane uwierzytelniające jako Base64(nazwa_użytkownika:hasło). Jest to kodowanie dla wygody transportu, NIE bezpieczeństwa — Base64 jest trywialnie odwracalne. Zawsze używaj HTTPS z Basic Auth.

Data URI

Data URI osadzają zawartość pliku bezpośrednio w HTML lub CSS: data:image/png;base64,.... Kodowanie Base64 obrazów i czcionek inline eliminuje żądania HTTP kosztem zwiększonego rozmiaru dokumentu (narzut ~33%).

Załączniki MIME w e-mailach

Poczta elektroniczna została zaprojektowana dla 7-bitowego ASCII. Binarne załączniki (obrazy, pliki PDF) są kodowane Base64 przez MIME przed transmisją. Klient poczty dekoduje je automatycznie podczas wyświetlania wiadomości.

Tokeny JWT

Tokeny JWT używają kodowania Base64url (wariant zastępujący + przez - i / przez _, bez dopełnienia) dla wszystkich trzech części (nagłówek, ładunek, podpis). Dzięki temu tokeny są bezpieczne w URL bez dodatkowego kodowania procentowego.

Parametry ciągu zapytania

Wszelkie dane dostarczone przez użytkownika w ciągach zapytania URL muszą być zakodowane procentowo. Nieodkodowanie & lub = w wartości po cichu uszkodzi parsowanie ciągu zapytania. Zawsze używaj encodeURIComponent dla pojedynczych wartości.

Umiędzynarodowione nazwy domen

Nazwy domen spoza ASCII (np. münchen.de) są kodowane przy użyciu Punycode (prefiks xn--) dla kompatybilności z systemem DNS. Przeglądarka wyświetla postać Unicode, ale wysyła postać Punycode do resolverów DNS.

Często zadawane pytania

Czy Base64 jest formą szyfrowania?

Nie. Base64 to kodowanie, nie szyfrowanie. Jest to odwracalna transformacja bez tajnego klucza. Każdy, kto zobaczy ciąg Base64, może go natychmiast zdekodować. Nigdy nie używaj Base64 jako środka bezpieczeństwa.

Dlaczego wynik Base64 czasami kończy się ==?

Base64 przetwarza dane wejściowe w grupach po 3 bajty. Jeśli dane wejściowe nie są wielokrotnością 3 bajtów, dodawane jest dopełnienie =, aby uzupełnić ostatnią grupę. Jeden = oznacza jeden bajt dopełnienia; == oznacza dwa. Niektóre implementacje pomijają dopełnienie (Base64url dla JWT).

Jaka jest różnica między Base64 a Base64url?

Base64url to wariant Base64 bezpieczny dla URL, który zastępuje + przez - i / przez _, i zazwyczaj pomija dopełnienie =. Dzięki temu można go bezpiecznie używać w URL-ach i nagłówkach HTTP bez kodowania procentowego. JWT używa Base64url dla wszystkich trzech części.

Kiedy powinienem używać encodeURI zamiast encodeURIComponent?

Używaj encodeURIComponent dla pojedynczych wartości (wartości parametrów zapytania, wartości segmentów ścieżki). Używaj encodeURI dla kompletnego ciągu URL, gdy chcesz zachować znaki struktury URL (/, :, ?, #). W razie wątpliwości używaj encodeURIComponent.

Dlaczego UTF-8 jest lepsze niż UTF-16 dla sieci?

UTF-8 jest kompatybilne z ASCII i efektywnie wykorzystuje miejsce dla tekstu łacińskiego (większość URL-ów, tagów HTML i kodu to ASCII). UTF-16 marnuje miejsce dla treści ASCII i nie jest wstecznie kompatybilne. HTTP i HTML domyślnie używają UTF-8.

Czym jest kodowanie procentowe?

Kodowanie procentowe (kodowanie URL) reprezentuje znaki jako % po którym następuje ich dwucyfrowa szesnastkowa wartość bajtu. Na przykład spacja to %20 (dziesiętnie 32, szesnastkowo 20). Wielobajtowe znaki UTF-8 kodują każdy bajt oddzielnie: é to %C3%A9.

Czy kodowanie wpływa na wydajność?

Base64 zwiększa rozmiar danych o około 33% i dodaje narzut procesora na kodowanie/dekodowanie. W systemach o wysokiej przepustowości preferuj protokoły binarne. Kodowanie URL dodaje minimalny narzut, ale może znacznie wydłużyć URL-e przy wielu znakach specjalnych.

Czym jest Punycode?

Punycode to kodowanie służące do reprezentowania znaków Unicode w kompatybilnym z ASCII systemie DNS. Umiędzynarodowione nazwy domen, takie jak münchen.de, są kodowane jako xn--mnchen-3ya.de w zapytaniach DNS. Przeglądarki wyświetlają postać Unicode, ale wewnętrznie używają Punycode.