Base64 ist eine Methode, Binärdaten (ein Bild, ein PDF, beliebige Bytes) nur mit 64 druckbaren Textzeichen darzustellen: den Buchstaben A-Z und a-z, den Ziffern 0-9 und den Symbolen + und /, mit = als Füllzeichen. Es existiert, um Binärdaten durch Kanäle zu transportieren, die für Text gedacht sind, etwa JSON, E-Mail, URLs oder HTML-Attribute. Es erhöht die Größe um etwa 33 % und ist keine Verschlüsselung: Jeder kann es dekodieren.
Dieser Artikel erklärt, wie es funktioniert, wann es sinnvoll ist (und wann nicht) und wie man in JavaScript, Node.js und im Terminal korrekt kodiert und dekodiert, einschließlich des Nicht-ASCII-Falls, an dem btoa scheitert.
Wie es funktioniert
Base64 nimmt die Daten in Blöcken von 3 Bytes (24 Bit) und teilt sie in 4 Gruppen zu 6 Bit. Jede 6-Bit-Gruppe (ein Wert von 0 bis 63) wird durch ein Zeichen aus der Tabelle ersetzt. Ist die Länge kein Vielfaches von 3, werden ein oder zwei = angehängt, um den letzten Block zu vervollständigen.
Daher kommen die Kosten: Aus jeweils 3 Bytes werden 4 Zeichen, das Ergebnis ist also 4/3 des Originals (33 % mehr), aufgerundet auf ein Vielfaches von 4. Der String Año 2026 ñ belegt zum Beispiel 12 Bytes in UTF-8, und sein Base64, QcOxbyAyMDI2IMOx, ist 16 Zeichen lang.
Die vollständige Spezifikation ist RFC 4648, die auch die URL-sichere Variante definiert: Sie ersetzt + durch - und / durch _, damit das Ergebnis ohne Maskierung in eine URL oder einen Dateinamen passt. JWT-Tokens verwenden diese Variante, meist ohne Füllzeichen.
Wann man Base64 einsetzt
- Eine kleine Ressource in HTML, CSS oder JSON einbetten: Ein SVG- oder PNG-Icon von wenigen KB als Data-URL spart eine HTTP-Anfrage.
- Binärdaten in einer JSON-API senden, wenn du
multipart/form-datanicht verwenden kannst. - E-Mail-Anhänge: Der MIME-Standard kodiert Anhänge in Base64, weil E-Mail ein Textprotokoll ist.
- HTTP-Basic-Authentifizierung: Der Header
Authorization: Basic ...transportiertnutzer:passwortin Base64. Das schützt nichts, weshalb es nur über HTTPS sinnvoll ist. - Schlüssel und Zertifikate im PEM-Format, die Base64 zwischen
-----BEGIN ... ------Zeilen sind.
Wann man es nicht einsetzt
- Um Informationen zu „verstecken“. Base64 wird mit einer Codezeile dekodiert. Brauchst du Vertraulichkeit, verschlüssele.
- Für große Bilder in HTML. Ein 300-KB-Foto in Base64 wird zu 400 KB, wird nicht separat gecacht und blockiert das HTML-Parsing. Oberhalb weniger KB liefere die Datei unter eigener URL aus (und konvertiere sie nach WebP).
- Für reinen Text in JSON. JSON transportiert bereits Unicode-Text; ihn in Base64 zu kodieren fügt nur 33 % Gewicht hinzu.
Kodieren und Dekodieren
Im Browser: btoa und atob (mit Vorsicht)
btoa() und atob() arbeiten mit Latin-1-Bytestrings, nicht mit Unicode-Text. Bei Zeichen außerhalb dieses Bereichs (ein ñ funktioniert; ein Emoji oder asiatische Zeichen nicht) wirft btoa einen InvalidCharacterError. Der richtige Weg geht zuerst über TextEncoder:
// UTF-8-Text nach Base64 kodieren
function toBase64(text) {
const bytes = new TextEncoder().encode(text);
let binary = '';
for (const b of bytes) binary += String.fromCharCode(b);
return btoa(binary);
}
// Base64 nach UTF-8-Text dekodieren
function fromBase64(b64) {
const binary = atob(b64);
const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
toBase64('Año 2026 ñ'); // "QcOxbyAyMDI2IMOx"
fromBase64('QcOxbyAyMDI2IMOx'); // "Año 2026 ñ"
Für Dateien (zum Beispiel ein vom Nutzer ausgewähltes Bild) verwende FileReader.readAsDataURL(), das direkt eine Data-URL mit dem Inhalt in Base64 zurückgibt.
In Node.js: Buffer
const b64 = Buffer.from('Año 2026 ñ', 'utf8').toString('base64'); // "QcOxbyAyMDI2IMOx"
const text = Buffer.from(b64, 'base64').toString('utf8'); // "Año 2026 ñ"
// URL-sichere Variante (ohne + / =)
const urlSafe = Buffer.from('Año 2026 ñ').toString('base64url');
// Eine ganze Datei
import { readFile } from 'node:fs/promises';
const png = await readFile('icon.png');
const dataUrl = `data:image/png;base64,${png.toString('base64')}`;
Buffer behandelt die Zeichenkodierung korrekt, der Umweg über TextEncoder ist also unnötig.
Im Terminal
# Eine Datei kodieren (GNU coreutils, Linux)
base64 bild.png > bild.b64
# Dekodieren
base64 -d bild.b64 > bild.png
# Einen String ohne abschließenden Zeilenumbruch kodieren
printf 'Año 2026 ñ' | base64
Unter macOS heißt die Dekodier-Option in älteren Versionen -D und in neueren -d oder --decode. Standardmäßig bricht das GNU-Werkzeug die Ausgabe nach 76 Zeichen um; -w 0 verhindert das.
Nichts zu installieren
Für eine einmalige Umwandlung kodiert und dekodiert der Encoder von AIMRAN Tools Base64 im Browser, ohne den Inhalt an einen Server zu senden. Das ist die bequeme Option, um ein Token, einen Anhang oder eine Data-URL zu inspizieren.
Data-URLs
Eine Data-URL bettet den Inhalt in die Adresse selbst ein: data:[MIME-Typ][;base64],daten.
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PC9zdmc+" alt="" width="10" height="10" />
Nützlich für kleine Icons und minimale CSS-Hintergründe. Bei SVG ist das Einbetten als URL-maskierter Text oft kompakter als Base64.
Häufige Fehler
btoamit Unicode-Text verwenden, ohne überTextEncoderzu gehen:InvalidCharacterError.- Den MIME-Typ in einer Data-URL vergessen: Der Browser weiß nicht, was er mit den Bytes anfangen soll.
- Standard- und URL-sichere Variante mischen: Ein als
-dekodiertes+korrumpiert die Daten. Nutze an beiden Enden dieselbe Variante. - Base64 als Sicherheit behandeln: In einer öffentlichen Datei „kodierte“ Zugangsdaten sind öffentliche Zugangsdaten.
- Große Ressourcen einbetten: mehr Gewicht, kein Caching und langsameres HTML-Parsing.
Fazit
Base64 löst ein konkretes Problem: Bytes durch einen Textkanal zu bewegen. Mach es mit Buffer in Node.js, mit TextEncoder + btoa im Browser oder mit base64 im Terminal, nutze die URL-sichere Variante, wenn das Ergebnis in eine URL kommt, und behalte seine zwei Grenzen im Kopf: Es vergrößert die Daten um ein Drittel und schützt nichts.