🔀

Base64 vs kodowanie URL: jaka jest różnica?

Dwa schematy kodowania, które brzmią podobnie i są nieustannie mylone. Oto co robi każdy, gdzie są używane i dlaczego nie powinieneś ich mylić.

· 5min czytania

“Kodowanie Base64” i “kodowanie URL” brzmią, jakby powinny robić podobne rzeczy - oba konwertują dane na inną reprezentację używając tylko bezpiecznych znaków. Ale rozwiązują różne problemy, produkują bardzo różne wyjście i działają w różnych miejscach. Mylenie ich to niezawodny sposób na psute API, masakrowane linki i godziny debugowania w złym miejscu.

Oba kodowania zestawione

Base64Kodowanie URL (percent-encoding)
CelReprezentacja danych binarnych jako tekstuUczynienie stringów bezpiecznymi dla URL-i
Alfabet64 znaki (A-Z, a-z, 0-9, +, /)Dowolny drukowalny ASCII, używa %XX dla niebezpiecznych znaków
Przyrost rozmiaruDokładnie +33%Zmienny (zwykle +0-200% zależnie od zawartości)
Używany wEmail, JSON, data URI, JWTURL-e, wysyłki formularzy, query stringi
WejścieBajtyTekst (zwykle string ze znakami specjalnymi)

Co naprawdę robi kodowanie URL

Kodowanie URL (formalnie percent-encoding, zdefiniowane w RFC 3986) pozwala umieścić dowolny tekst w URL bez jego psucia.

URL-e mają strukturę:

https://example.com/search?q=coffee&lang=en

Pewne znaki mają specjalne znaczenie: ? oddziela ścieżkę od query stringa, & oddziela parametry, = oddziela klucz od wartości, / oddziela segmenty ścieżki, # rozpoczyna fragment.

Jeśli chcesz zawrzeć któryś z tych znaków jako dane - powiedzmy zapytanie “A & B” - musisz je escape’ować. Kodowanie URL zastępuje każdy znak specjalny znakiem % i dwucyfrowym kodem szesnastkowym ASCII:

  • Spacja → %20 (lub + w query stringach)
  • &%26
  • =%3D
  • #%23

A & B staje się więc A%20%26%20B. Bezpieczne znaki (litery, cyfry, -, _, ., ~) przechodzą nienaruszone. Dla wejścia pełnego znaków specjalnych wynik potrafi być kilkukrotnie dłuższy.

Co naprawdę robi Base64

Base64 to zupełnie inna historia. Bierze bajty - niekoniecznie tekst - i produkuje string z 64-znakowego alfabetu. Każde 3 bajty wejścia stają się 4 znakami wyjścia, zawsze.

Base64 nie dba o to, czym jest wejście. Traktuje wszystko jako bajty i wyprowadza string bezpieczny do umieszczenia praktycznie wszędzie, gdzie spodziewany jest tekst. Wyjście jest dokładnie 33% dłuższe od wejścia (plus padding do wielokrotności 4 znakami =).

Sięgasz po Base64, gdy musisz przepuścić dane binarne (obraz PNG, plik zip, zaszyfrowany blob) przez kanał tylko tekstowy jak email albo JSON. Kodowanie URL tego nie obsłuży - jest projektowane do transformacji tekst-do-tekstu, nie do dowolnych binarów.

Kiedy potrzebujesz obu naraz

Jest jeden konkretny scenariusz, gdzie oba kodowania się spotykają: umieszczanie danych binarnych w URL-u.

Masz maleńki obraz (20 bajtów PNG) i chcesz go osadzić w URL jako parametr:

  1. Zakoduj obraz w Base64 → dostajesz 28-znakowy string
  2. Zakoduj ten string w URL → znaki +, / i = stają się %2B, %2F, %3D

Ponieważ ta kombinacja jest tak powszechna, istnieje wariant Base64 URL-safe. Używa - i _ zamiast + i / (bezpieczne w URL-ach bez escape’owania) i pomija padding =:

  • Standardowy Base64: a+b/c=
  • URL-safe Base64: a-b_c

JWT (JSON Web Tokens) używają właśnie URL-safe Base64 - stąd te stringi eyJhbGciOiJIUzI1NiJ9 bez żadnych + czy /.

Przykład obok siebie

Wejście: tekst Hello, world! (13 bajtów)

Kodowanie URL (escape’uje przecinek, spację i !):

Hello%2C%20world%21

Długość: 19 znaków. Wciąż czytelne.

Kodowanie Base64 (13 bajtów → tekst):

SGVsbG8sIHdvcmxkIQ==

Długość: 20 znaków. Nieczytelne.

URL-safe Base64 (bez znaków wymagających escape’owania):

SGVsbG8sIHdvcmxkIQ

Długość: 18 znaków. Używane w JWT i kompaktowych ID.

Kiedy używać kodowania URL

Po kodowanie URL sięgasz, gdy:

  • Osadzasz dane użytkownika w ścieżce URL lub query stringu - wszystko, co człowiek wpisuje w pole wyszukiwania, wymaga kodowania URL przed wejściem do URL-a
  • Escape’ujesz znaki specjalne w wysyłkach formularzy - formularze HTML domyślnie wysyłają dane URL-encoded
  • Budujesz URL-e REST API z dynamicznymi parametrami (nazwy użytkowników, ID ze znakami specjalnymi, ścieżki plików)

Nie używaj kodowania URL do danych binarnych - bajty non-ASCII obsługuje niekonsekwentnie i marnuje miejsce na %-escape’y. Do plików binarnych najpierw Base64, potem ewentualnie kodowanie URL wyniku.

Kiedy używać Base64

Po Base64 sięgasz, gdy:

  • Transmitujesz dane binarne przez kanał tylko tekstowy (JSON, email, XML)
  • Osadzasz małe pliki w HTML lub CSS przez data URI
  • Pracujesz z tokenami, certyfikatami, danymi kryptograficznymi, które przychodzą jako bajty, ale muszą być przechowywane jako tekst
  • Udostępniasz pliki przez kopiuj-wklej, gdzie plik binarny by nie przeżył

Nie używaj Base64, gdy dane są już tekstem i potrzebujesz tylko escape’ować znaki dla URL - do tego służy kodowanie URL. I nie używaj go, gdy kanał jest binarnie bezpieczny - po prostu wyślij bajty bez zbędnego 33% narzutu.

Typowe scenariusze pomyłek

”Zakodowałem string w Base64, żeby umieścić go w URL, i wciąż jest zepsute”

Wyjście Base64 zawiera +, / i = - znaki ze specjalnym znaczeniem w URL-ach. Musisz albo zakodować string Base64 w URL, albo użyć wariantu URL-safe Base64 (który zamiast + i / używa - i _).

”Zakodowałem plik w URL, ale jest uszkodzony”

Kodowanie URL traktuje wejście jako tekst. Bajty non-ASCII są obsługiwane niekonsekwentnie zależnie od zakładanego kodowania. Dla plików binarnych Base64 najpierw, kodowanie URL wyniku tylko jeśli konieczne.

”API mówi, żeby zakodować hasło w Base64 dla Basic Auth”

HTTP Basic Auth bierze username:password, koduje cały string w Base64 i umieszcza w nagłówku Authorization. To nie dlatego, że Base64 jest bezpieczne - nie jest. Chodzi o to, że nagłówek musi przetrwać transmisję przez systemy, które mogłyby zmasakrować surowy tekst z dwukropkami i znakami specjalnymi. Bezpieczeństwo pochodzi z HTTPS, nie z Base64.

Praktyczny workflow

Nasze narzędzie Base64 obsługuje kodowanie i dekodowanie bez zbędnych kroków:

  • Wklej tekst → dostajesz Base64 (do osadzenia w JSON, data URI itd.)
  • Wklej Base64 → dostajesz tekst (do czytania JWT, dekodowania tokenów)
  • Wgraj plik → dostajesz Base64 (do transmisji pliku jako tekstu)

Dla samego kodowania URL każdy język ma jednolinijkowiec:

  • JavaScript: encodeURIComponent(str) / decodeURIComponent(str)
  • Python: urllib.parse.quote(str) / urllib.parse.unquote(str)
  • PHP: urlencode($str) / urldecode($str)
  • Ruby: CGI.escape(str) / CGI.unescape(str)

Dla scenariuszy łączonych (dane binarne w URL) standardowy wzorzec to: najpierw Base64, potem kodowanie URL jeśli potrzebne - albo od razu URL-safe Base64.

Zasada prosta do zapamiętania: kodowanie URL dla tekst-do-URL, Base64 dla bajty-do-tekstu. Gdy to zinternalizujesz, pomyłki znikają. A narzędzie Base64 jest do tłumaczenia bajty-do-tekstu, działa lokalnie - więc nawet wrażliwe tokeny zostają na twoim urządzeniu.