Przejdź do treści
Toova
Wszystkie narzędzia

Zrozumieć Kodowanie Base64 — Kompletny Przewodnik Programisty

Toova

Kodowanie Base64 pojawia się w niemal każdym obszarze rozwoju webowego - tokeny JWT, data URIs, załączniki e-mail, payloady API, podpisy kryptograficzne i pliki konfiguracyjne. Mimo że jest wszechobecne, jest często źle rozumiane: programiści czasami mylą je z szyfrowaniem lub używają w sytuacjach, gdzie czyni rzeczy gorszymi. Ten przewodnik wyjaśnia dokładnie, jak działa Base64, kiedy po nie sięgać, kiedy unikać i jak używać go poprawnie w JavaScript.

Czym Jest Kodowanie Base64 (a Czym Nie Jest)

Base64 to schemat kodowania binarne-na-tekst. Jego jedyną pracą jest konwertowanie dowolnych danych binarnych w string drukowalnych znaków ASCII. Nie kompresuje danych, nie szyfruje danych i nie waliduje danych. To czysto transformacja reprezentacji - branie bajtów, które mogą zawierać bajty null, znaki kontrolne lub wartości łamiące protokoły oparte na tekście, i konwertowanie ich do bezpiecznego zestawu znaków.

Nazwa pochodzi od 64 drukowalnych znaków używanych jako alfabet kodowania: A-Z (26 znaków), a-z (26 znaków), 0-9 (10 znaków), plus + i / (2 znaki). Znak = jest używany do paddingu. Ponieważ jest 64 możliwych wartości na pozycję znaku i 2^6 = 64, każdy znak Base64 koduje dokładnie 6 bitów oryginalnych danych.

Jak Działa Base64 — "Hello" Krok po Kroku

Najlepszy sposób zrozumienia Base64 to prześledzenie konkretnego przykładu. Zakodujmy string Hello.

Krok 1: Konwersja na bajty

Każdy znak w Hello mapuje się na swój kod ASCII, który następnie wyraża się binarnie (8 bitów na bajt):

H  e  l  l  o
72 65 6C 6C 6F   (ASCII / hex)
01001000 01100101 01101100 01101100 01101111   (binarnie)

Krok 2: Grupowanie w 6-bitowe kawałki

Połącz wszystkie bity: 0100100001100101011011000110110001101111 (40 bitów). Base64 przetwarza 3 bajty (24 bity) naraz i mapuje je na 4 znaki Base64 (4 × 6 = 24 bity). Pogrupuj 40 bitów w 6-bitowe kawałki, dopełniając ostatnią grupę zerami:

010010 000110 010101 101100 011011 000110 1111
18     6      21     44     27     6      (ostatnia grupa dopełniona do 6 bitów: 111100 = 60)

Krok 3: Mapowanie na alfabet Base64

Każda 6-bitowa wartość mapuje się na znak w alfabecie Base64 (A=0, B=1, ... Z=25, a=26, ... z=51, 0=52, ... 9=61, +=62, /=63). Ponieważ 5 bajtów to nie wielokrotność 3, dodawany jest jeden znak paddingu =:

Indeks: 18  6   21  44  27  6   60
Znak:   S   G   V   s   b   G   8
Wynik:  SGVsbG8=   (= to padding)

Wynik

"Hello" → "SGVsbG8="

Możesz to natychmiast zweryfikować koderem/dekoderem Base64 Toova - wklej Hello, kliknij Encode, dostaniesz SGVsbG8=. Kliknij Decode, aby odwrócić.

33% Narzut Rozmiaru

Kodowanie Base64 zawsze zwiększa rozmiar danych o około 33%. Matematyka jest prosta: 3 bajty wejścia (24 bity) produkują 4 znaki Base64 (24 bity zakodowane w 4 × 6-bitowych grupach). To stosunek 4/3, czyli 33,3% narzutu. Dodaj znaki paddingu, a prawdziwy narzut wynosi między 33% a 36%, w zależności od długości wejścia.

To ma znaczące znaczenie dla wydajności. Obraz 1 MB osadzony jako data URI Base64 w HTML staje się mniej więcej 1,37 MB. API kodujące wszystkie payloady binarne w Base64 wysyła 33% więcej danych, niż to konieczne. Dla małych wartości jak krótkie tokeny lub sumy kontrolne, narzut jest pomijalny. Dla dużych plików to prawdziwy koszt.

Wariant URL-Safe

Standardowy Base64 używa + i / jako dwóch ostatnich znaków alfabetu. Oba są problematyczne w URL:

  • + jest dekodowane jako znak spacji w query stringach
  • / to separator ścieżki w URL

URL-safe Base64 (zwany też Base64url, zdefiniowany w RFC 4648 Sekcja 5) zastępuje + przez - i / przez _. Padding (=) jest zwykle pomijany w kontekstach URL-safe, ponieważ może też być źle zinterpretowany przez niektóre parsery URL.

Tokeny JWT używają Base64url bez paddingu. Gdy dekodujesz nagłówek lub payload JWT ręcznie, musisz obsłużyć zarówno zamianę znaków, jak i brakujący padding. Oto jak to zrobić w JavaScript:

// Base64 URL-safe (zastąp + przez - i / przez _)
function toBase64Url(base64) {
  return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}

function fromBase64Url(base64url) {
  const padded = base64url.padEnd(
    base64url.length + (4 - base64url.length % 4) % 4,
    '='
  );
  return atob(padded.replace(/-/g, '+').replace(/_/g, '/'));
}

Koder/dekoder Base64 Toova obsługuje zarówno warianty standardowy, jak i URL-safe pojedynczym przełącznikiem.

Base64 w JavaScript

Przeglądarka: btoa() i atob()

Przeglądarki dostarczają dwie wbudowane funkcje: btoa() (binary to ASCII, czyli koduj) i atob() (ASCII to binary, czyli dekoduj). Mimo mylącej kolejności nazw, są dostępne w przeglądarkach od ponad dekady.

// Przeglądarka - atob / btoa (tylko stringi, bezpieczne ASCII)
const encoded = btoa("Hello");
console.log(encoded); // "SGVsbG8="

const decoded = atob("SGVsbG8=");
console.log(decoded); // "Hello"

Ważne ograniczenie: btoa() akceptuje tylko stringi ze znakami w zakresie Latin-1 (punkty kodowe 0-255). Jeśli przekażesz string ze znakami Unicode jak emoji lub znakami CJK, rzuca DOMException. Aby zakodować dowolne dane binarne, konwertuj je najpierw na Uint8Array:

// Przeglądarka - kodowanie dowolnego binarna (Uint8Array)
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
const encoded = btoa(String.fromCharCode(...bytes));
console.log(encoded); // "SGVsbG8="

Do kodowania dowolnych stringów, które mogą zawierać znaki Unicode, rekomendowanym nowoczesnym podejściem jest użycie TextEncoder, aby najpierw uzyskać Uint8Array, a następnie zakodować jak pokazano powyżej.

Node.js: Buffer

Node.js dostarcza klasę Buffer obsługującą poprawnie dane binarne i wspierającą wiele kodowań, włącznie z Base64 i Base64url:

// Node.js - Buffer (obsługuje binaria bezpiecznie)
const encoded = Buffer.from('Hello').toString('base64');
console.log(encoded); // "SGVsbG8="

const decoded = Buffer.from('SGVsbG8=', 'base64').toString('utf8');
console.log(decoded); // "Hello"

// Wariant URL-safe w Node.js
const urlSafe = Buffer.from('Hello').toString('base64url');
console.log(urlSafe); // "SGVsbG8" (bez paddingu)

Opcja kodowania base64url (dostępna od Node.js 16) obsługuje automatycznie zamianę znaków i usuwanie paddingu, czyniąc ją znacznie łatwiejszą niż ręczne wykonywanie transformacji.

Dla środowisk przeglądarki potrzebujących obsłużyć duże pliki binarne, metoda FileReader.readAsDataURL koduje plik jako data URI Base64 bez ładowania wszystkiego do pamięci naraz.

Kiedy Używać Base64

Osadzanie danych binarnych w protokołach tylko tekstowych

Oryginalnym przypadkiem użycia Base64 było kodowanie binarnych załączników e-mail w SMTP, protokole obsługującym tylko 7-bitowy tekst ASCII. Ta sama zasada obowiązuje wszędzie tam, gdzie musisz włączyć dane binarne do formatu nieobsługującego surowych bajtów: payloady JSON API, dokumenty XML, atrybuty HTML, wartości CSS, nagłówki HTTP.

Data URIs dla małych zasobów

CSS i HTML pozwalają osadzać obrazy, czcionki i SVG jako data URI Base64. To eliminuje round-trip HTTP dla małych zasobów jak ikony i eliminuje flash-of-unstyled-content dla krytycznych obrazów above-the-fold.

<!-- Inline SVG icon jako Base64 data URI -->
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c..." alt="ikona" />

<!-- Inline tło CSS -->
.icon {
  background-image: url("data:image/png;base64,iVBORw0KGgo...");
}

Kompromis: data URI Base64 nie mogą być cache'owane oddzielnie od pliku HTML/CSS je zawierającego. Jeśli obraz nigdy się nie zmienia, ale otaczający HTML tak, przeglądarka pobiera ponownie dane obrazu przy każdym przeładowaniu strony. Używaj data URI tylko dla małych zasobów (najlepiej poniżej 4 KB), gdzie eliminacja round-tripu przeważa nad karą cache.

Kodowanie danych binarnych dla JSON lub parametrów URL

JSON to format tekstowy - nie może bezpośrednio reprezentować surowych bajtów binarnych. Gdy API musi przekazywać dane binarne (miniaturki obrazów, podpisy kryptograficzne, skompresowane dane), Base64 to standardowy sposób włączenia ich do payloadu JSON. Podobnie, jeśli musisz przekazać dane binarne w parametrze query URL, kodowanie Base64url zapewnia, że dane przetrwają procentowe kodowanie bez uszkodzenia.

JWT i inne formaty tokenów

Tokeny JWT używają Base64url do kodowania swoich sekcji nagłówka i payloadu. To czyni token drukowalnym, URL-safe stringiem, który może być przekazywany w nagłówkach HTTP, ciasteczkach lub parametrach URL. Kodowanie nie jest dla bezpieczeństwa (payload jest czytelny dla każdego z tokenem) - jest czysto dla bezpiecznej transmisji.

Kiedy NIE Używać Base64

Bezpieczeństwo lub poufność

Base64 zapewnia zero bezpieczeństwa. Jest trywialnie odwracalne w milisekundach. Nie używaj go do "obfuskacji" haseł, kluczy API lub wrażliwych wartości konfiguracyjnych. Każdy programista, który widzi string Base64, zdekoduje go natychmiast. Jeśli potrzebujesz poufności, użyj szyfrowania.

Przechowywanie haseł

Przechowywanie haseł zakodowanych Base64 jest tym samym co przechowywanie ich jako zwykły tekst - kodowanie jest natychmiast odwracalne. Hasła muszą być hashowane właściwą funkcją hashowania haseł jak bcrypt, Argon2 lub scrypt.

Duże pliki binarne

Kodowanie pliku 10 MB jako Base64 produkuje string 13,7 MB. Jeśli przechowujesz to w kolumnie bazy danych, przeszukujesz lub transmitujesz przez API, płacisz 33% narzut za każdym razem. Dla dużych danych binarnych użyj dedykowanej pamięci binarnej: kolumn BLOB/BYTEA bazy danych, object storage jak S3 lub GCS, lub strumieniuj binaria bezpośrednio.

Sytuacje, gdzie możesz używać binarna bezpośrednio

Jeśli twój protokół lub format obsługuje surowy binar - na przykład WebSocket z binarnym typem wiadomości, upload HTTP multipart/form-data lub binarny format pliku - używaj binarna bezpośrednio. Base64 jest konieczne tylko gdy medium transportu autentycznie nie obsługuje surowych bajtów.

Częste Pułapki

Mylenie kodowania z szyfrowaniem

To najczęstszy błąd. Base64 jest widoczne. To nie jest mechanizm bezpieczeństwa. Komentarze w kodzie typu "hasło jest przechowywane zakodowane Base64 dla bezpieczeństwa" wskazują na poważne niezrozumienie, które powinno być wyłapane w przeglądzie kodu.

Używanie btoa() ze stringami Unicode

Wywołanie btoa() na stringu zawierającym znaki z punktami kodowymi powyżej 255 rzuca DOMException: Failed to execute 'btoa': The string to be encoded contains characters outside of the Latin1 range. Zawsze konwertuj na Uint8Array przez TextEncoder przed kodowaniem stringów mogących zawierać znaki Unicode.

Zapominanie o paddingu przy dekodowaniu

Stringi Base64 muszą mieć długości będące wielokrotnościami 4. Jeśli string Base64 został wygenerowany bez paddingu (częste w kodowaniu URL-safe), musisz dodać z powrotem poprawną liczbę znaków = przed dekodowaniem. String Base64 o długości n potrzebuje (4 - n % 4) % 4 znaków paddingu. Zapomnienie tego powoduje błędy dekodowania trudne do zdiagnozowania.

Podwójne kodowanie

String Base64 sam w sobie jest poprawnym ASCII, więc btoa(btoa(data)) działa bez błędów, ale produkuje podwójnie zakodowane wyjście. Przy przekazywaniu wartości Base64 przez wiele warstw serializacji (JSON w JSON na przykład), łatwo zakodować te same dane dwa razy. Zawsze dekoduj dokładnie tyle razy, ile kodowałeś.

Szybka Referencja: Base64 w Praktyce

Do kodowania i dekodowania w przeglądarce bez pisania kodu, koder/dekoder Base64 Toova działa całkowicie w twojej przeglądarce - bez round-tripu serwerowego. Obsługuje warianty standardowy i URL-safe, upload plików do kodowania plików binarnych oraz wyjście tekstowe i hex dla zdekodowanych danych.

Jeśli pracujesz z zakodowaną zawartością w URL, koder/dekoder URL obsługuje procentowe kodowanie oddzielnie od Base64. Dla encji HTML, konwerter encji HTML obsługuje escapowanie znaków w kontekstach HTML. To odrębne schematy kodowania - każdy ma konkretny przypadek użycia.

Kanoniczna referencja dla Base64 to RFC 4648, definiująca standardowy Base64 (Sekcja 4), Base64url (Sekcja 5) i Base32 (Sekcje 6-7). Dla API przeglądarki btoa() i atob(), dokumentacja MDN dla btoa() szczegółowo pokrywa kompatybilność przeglądarek i ograniczenie Unicode.

Podsumowanie

Kodowanie Base64 konwertuje dane binarne na drukowalny ASCII używając 64-znakowego alfabetu. Zwiększa rozmiar danych o 33%, jest całkowicie odwracalne i nie zapewnia bezpieczeństwa. Używaj go, gdy musisz osadzić dane binarne w formacie opartym na tekście - payloady JSON, data URI HTML, tokeny JWT, załączniki e-mail, parametry URL. Unikaj, gdy potrzebujesz bezpieczeństwa, gdy transport obsługuje binaria bezpośrednio lub gdy 33% narzut ma znaczenie w skali.

Zrozumienie, czym jest Base64 - a czym nie jest - zapobiega najczęstszym błędom: używaniu go dla bezpieczeństwa, stosowaniu go do dużych plików niepotrzebnie i myleniu go z innymi schematami kodowania jak kodowanie URL czy encje HTML. Każdy schemat kodowania rozwiązuje konkretny problem. Base64 rozwiązuje dokładnie jeden: czynienie danych binarnych bezpiecznymi dla kanałów tylko tekstowych.

Gotowy na kodowanie lub dekodowanie? Wypróbuj koder/dekoder Base64 Toova - wklej tekst lub upuść plik, przełączaj między standardowym a URL-safe i skopiuj wynik. Bez konta, bez serwera, bez limitów.