Programiści

Co to jest kodowanie Base64? Jak działa i gdzie się go używa

8 min czytania

Kodowanie Base64 to sposób zapisu dowolnych danych, tekstu, obrazu, dowolnych bajtów, za pomocą tylko 64 drukowalnych znaków ASCII, żeby dane bezpiecznie przeszły przez systemy obsługujące wyłącznie tekst. Alfabet Base64 to litery A-Z, a-z, cyfry 0-9, plus znaki + i /, razem 64 symbole, do których dochodzi jeszcze = jako znak dopełnienia. Każde 3 bajty danych wejściowych zamieniają się w dokładnie 4 znaki Base64, więc wynik jest zawsze około 33% większy od oryginału.

Czego Base64 nie robi

Zanim przejdziemy do mechaniki, jedna rzecz musi być jasna: Base64 to nie jest szyfrowanie ani kompresja. Nie ma tu żadnego klucza, nie ma tajemnicy, każdy może zdekodować ciąg Base64 z powrotem do oryginału w ułamku sekundy, a wynik jest większy od danych wejściowych, nie mniejszy. To najczęstsze nieporozumienie wokół Base64: ktoś “koduje” hasło albo token do Base64 i traktuje to jako ochronę danych. Nie jest. Base64 zmienia tylko format zapisu, nie ukrywa treści przed nikim, kto wie, że to Base64, a rozpoznać to po samym wyglądzie ciągu jest banalnie łatwo. Jeśli potrzebujesz poufności, potrzebujesz prawdziwego szyfrowania, nie kodowania.

Jak to działa: kodowanie “Man” bit po bicie

Base64 nie jest żadną magią, to konwersja podstawy z 8-bitowych bajtów na 6-bitowe porcje. Weźmy tekst “Man” i przejdźmy cały proces krok po kroku.

Najpierw każdy znak zamienia się na swoją wartość ASCII, a potem na 8-bitowy zapis binarny:

ZnakWartość ASCIIZapis binarny (8 bitów)
M7701001101
a9701100001
n11001101110

Sklejone razem te trzy bajty dają 24 bity: 010011010110000101101110.

Base64 nie czyta tych bitów po 8, tylko po 6, bo 6 bitów daje dokładnie 64 możliwe kombinacje, czyli tyle, ile ma znaków alfabet Base64. Dzielimy więc 24 bity na cztery grupy po 6:

010011 | 010110 | 000101 | 101110

Każdą grupę zamieniamy na liczbę dziesiętną, a tę liczbę na znak z alfabetu Base64:

Grupa 6-bitowaWartość dziesiętnaZnak Base64
01001119T
01011022W
0001015F
10111046u

Wynik: Man staje się TWFu. Trzy bajty zamieniły się w cztery znaki, dokładnie jak mówi zasada 3 bajty na 4 znaki. Żadnej magii, tylko inny sposób grupowania tych samych bitów.

Dopełnienie: dlaczego niektóre ciągi Base64 kończą się na =

Algorytm działa czysto tylko wtedy, gdy dane wejściowe da się podzielić na kompletne trójki bajtów. Kiedy zostaje 1 albo 2 bajty na końcu, Base64 dopełnia brakujące miejsce znakiem =, żeby długość wyniku zawsze była wielokrotnością 4.

Tekst wejściowyBajtówWynik Base64Co się dzieje
M1TQ==2 znaki realnych danych + 2 znaki dopełnienia
Ma2TWE=3 znaki realnych danych + 1 znak dopełnienia
Man3TWFu4 znaki, bez dopełnienia

Jeden bajt nie wypełnia całej trójki, więc dekoder dostaje tylko część informacji potrzebnej do złożenia pełnych 6-bitowych grup, stąd dwa = przy TQ==. Dwa bajty wypełniają trójkę częściowo, stąd jeden = przy TWE=. Trzy bajty to pełna trójka, więc TWFu nie potrzebuje żadnego dopełnienia. To właśnie te znaki = na końcu długiego ciągu Base64 zdradzają, ile bajtów zostało “nadmiarowych” w ostatniej grupie.

Gdzie naprawdę spotkasz Base64

Base64 nie jest ciekawostką akademicką, pojawia się w wielu miejscach, z którymi programiści stykają się codziennie:

Przykład wejściowyKontekst użyciaWynik Base64
Hello, World!zwykły tekstSGVsbG8sIFdvcmxkIQ==
user:pass1234nagłówek HTTP Basic AuthdXNlcjpwYXNzMTIzNA==
{"id":42,"active":true}mały payload JSON w URL-u albo w segmencie JWTeyJpZCI6NDIsImFjdGl2ZSI6dHJ1ZX0=
cafétekst z akcentem, UTF-8Y2Fmw6k=
🚀emoji, UTF-88J+agA==

Nagłówek Authorization: Basic <base64(login:hasło)> w HTTP Basic Authentication to dosłownie ten mechanizm w akcji: przeglądarka albo klient API zamienia user:pass1234 na dXNlcjpwYXNzMTIzNA== i wysyła to jako nagłówek. Podobnie działa osadzanie małego pliku, na przykład ikony, bezpośrednio w kodzie CSS albo HTML jako data: URL, zamiast trzymać go w osobnym pliku. Załączniki e-mail w formacie MIME również lecą jako Base64, bo protokół pocztowy z lat 80. potrafi bezpiecznie przenosić tylko tekst.

Tokeny JWT (JSON Web Token) to trzy segmenty Base64url oddzielone kropkami: header.payload.signature. Środkowy segment, payload, to zwykły JSON zakodowany w Base64, więc wystarczy wkleić go do dekodera Base64, żeby zobaczyć, jakie dane niesie token, na przykład ID użytkownika czy datę wygaśnięcia. Podpis (trzeci segment) to co innego, kryptograficzna sygnatura, ale sam payload odczytasz zwykłym dekoderem Base64, tym samym, którego użyjesz niżej na tej stronie.

Warto zwrócić uwagę na café i 🚀: to przykłady tego, że Base64 koduje bajty, nie znaki. é w UTF-8 zajmuje 2 bajty, więc czteroliterowe słowo café (a, é liczy się jako jeden znak, ale dwa bajty) daje w sumie 5 bajtów wejściowych i 8 znaków Base64 na wyjściu, więcej niż intuicyjnie sugerowałoby liczenie po znakach. Emoji 🚀 to w UTF-8 aż 4 bajty, mimo że wizualnie to jeden “znak”, i te 4 bajty kodują się tak samo jak każde inne dane binarne.

Zakoduj lub zdekoduj własny tekst

Wpisz dowolny tekst poniżej, żeby zobaczyć jego zapis w Base64, albo wklej gotowy ciąg Base64, żeby odczytać, co się pod nim kryje.

Enkoder Base64
Za darmo, bez rejestracji, na każdym urządzeniu.
Otwórz pełne narzędzie

Częste błędy i przypadki szczególne

Traktowanie Base64 jako zabezpieczenia. To nie technikalia, to realny błąd bezpieczeństwa. Base64 nie ma klucza, nie ma sekretu, każdy z dostępem do zakodowanego ciągu może go zdekodować w jednej linijce kodu. Jeśli w logach albo w bazie danych widzisz hasło “zakodowane w Base64”, to hasło jest w praktyce jawne.

Standardowy Base64 nie jest bezpieczny dla adresów URL. Znaki +, / i = mają specjalne znaczenie w URL-ach i nazwach plików, więc surowy Base64 wklejony do parametru zapytania może zostać uszkodzony albo źle zinterpretowany. Dlatego istnieje odmiana Base64url, która zamienia + na - i / na _, a często w ogóle pomija dopełnienie =. Jeśli widzisz w URL-u ciąg przypominający Base64, ale bez +, / czy =, to najpewniej właśnie ta odmiana, dokładnie ta, której używają segmenty tokenów JWT.

Białe znaki i brakujące dopełnienie psują dekodowanie. Niektóre dekodery, zwłaszcza te napisane rygorystycznie, odrzucą ciąg Base64 ze spacją, złamaniem linii w środku albo z brakującym = na końcu. Jeśli kopiujesz ciąg Base64 z e-maila albo z pliku tekstowego, sprawdź, czy przypadkiem nie wkradł się tam znak nowej linii.

Wielobajtowy tekst UTF-8 zaskakuje długością wyniku. Akcenty, znaki CJK (chińskie, japońskie, koreańskie) czy emoji zajmują więcej niż 1 bajt na znak, więc liczba widocznych znaków wcale nie odpowiada liczbie bajtów wejściowych, a to właśnie liczba bajtów decyduje o długości wyniku Base64. Przykłady café i 🚀 wyżej pokazują to dokładnie.

Podwójne kodowanie przez pomyłkę. Zakodowanie już zakodowanego ciągu Base64 jeszcze raz jest łatwym błędem, zwłaszcza w skryptach, które łączą wiele kroków. Efekt: jedno dekodowanie zwraca nie oryginalny tekst, tylko kolejny ciąg Base64, który wygląda jak bezsensowny bełkot, dopóki nie zdekodujesz go po raz drugi.

Najczęściej zadawane pytania

Czym różni się kodowanie od szyfrowania? Kodowanie, takie jak Base64, to tylko zmiana formatu zapisu danych, odwracalna przez każdego bez żadnego sekretu. Szyfrowanie wymaga klucza i ma za zadanie ukryć treść przed osobami bez tego klucza. Base64 nie chroni niczego, jedynie zapisuje dane w formacie bezpiecznym dla systemów tekstowych.

Dlaczego wynik Base64 jest większy od oryginału? Bo każde 3 bajty danych wejściowych (24 bity) zamieniają się na 4 znaki Base64, a każdy znak reprezentuje tylko 6 bitów zamiast 8. Ten narzut daje w efekcie wynik około 33% większy niż dane źródłowe, niezależnie od tego, co koduje.

Czy Base64 obsługuje polskie znaki i emoji? Tak, bo Base64 działa na poziomie bajtów, nie znaków. Tekst jest najpierw zamieniany na bajty w UTF-8, a dopiero te bajty trafiają do algorytmu Base64, więc ą, ę, ż czy emoji kodują się bezproblemowo, tylko zajmują więcej bajtów niż zwykłe litery ASCII.

Co oznaczają znaki = na końcu ciągu Base64? To dopełnienie, które pojawia się, gdy liczba bajtów wejściowych nie dzieli się równo przez 3. Jeden znak = oznacza, że ostatnia grupa miała 2 bajty zamiast 3, dwa znaki == oznaczają, że została tylko 1 bajt. Ciąg, który dzieli się idealnie na trójki, nie potrzebuje żadnego dopełnienia.

Czy mogę zdekodować token JWT w tym dekoderze? Środkowy segment tokenu JWT (payload, między dwiema kropkami) to zwykły JSON zakodowany w Base64url, więc dekoder poniżej odczyta go bez problemu. Podpis w trzecim segmencie to jednak dane kryptograficzne, nie zwykły tekst, więc jego zdekodowanie nie da czytelnej treści, to zresztą działa zgodnie z zamysłem: podpis ma potwierdzać integralność tokenu, nie nieść informacji.

Base64KodowanieProgramowanieAPI
Enkoder Base64
Teraz wypróbuj samodzielnie w pełnym narzędziu.
Wypróbuj teraz
Powiązane narzędzia