Datei hochladen
  1. base64hub
  2. Base64 im Code
  3. Bash
Code

Base64 in Bash

Die eigentliche Arbeit erledigt der Befehl base64; Bash leitet nur die Daten hinein. GNU coreutils unter Linux und das BSD-Tool unter macOS kennen unterschiedliche Optionen. Die Linux-Ausgaben unten stammen von GNU coreutils 9.7.

Einen String kodieren und dekodieren

printf '%s' 'héllo wörld' | base64          # aMOpbGxvIHfDtnJsZA==
printf '%s' 'aMOpbGxvIHfDtnJsZA==' | base64 -d   # héllo wörld

base64 kodiert Bytes, das Ergebnis hängt also von der Kodierung Ihres Terminals ab. Auf jedem aktuellen Linux- oder macOS-System ist das UTF-8.

Der klassische Fehler ist echo, das einen Zeilenumbruch anhängt:

echo 'héllo wörld' | base64      # aMOpbGxvIHfDtnJsZAo=   (note the "o=")
echo -n hi | base64              # aGk=

echo -n funktioniert in Bash, aber nicht in jeder sh; printf '%s' ist portabel. Auch ein Here-String (base64 <<< "text") hängt einen Zeilenumbruch an. Endet Base64, das Ihnen jemand schickt, auf Cg== oder o=, enthält es wahrscheinlich einen abschließenden Zeilenumbruch; fügen Sie es zur Kontrolle in den Base64-Decoder ein.

Optionen von GNU (Linux) und BSD (macOS)

AufgabeGNU coreutils (Linux)macOS
Dekodieren-d, --decode-D, --decode (neuere Versionen auch -d)
Kein Zeilenumbruch-w 0Standard
Umbruch nach N Zeichen-w N (Standard 76)-b N
Eingabedateibase64 filebase64 -i file oder base64 < file
AusgabedateiUmleitung >-o file oder Umleitung
Fremdzeichen beim Dekodieren ignorieren-i, --ignore-garbagenicht verfügbar

Die beiden -i-Optionen bedeuten Verschiedenes: Unter macOS benennt sie die Eingabedatei, unter Linux ignoriert sie Fremdzeichen. Portable Skripte lesen von stdin und schreiben nach stdout:

base64 < in.bin | tr -d '\n' > out.b64     # same output on Linux and macOS
base64 --decode < out.b64 > in-copy.bin

GNU base64 bricht standardmäßig nach 76 Zeichen um, was Header und Umgebungsvariablen kaputt macht:

head -c 60 /dev/zero | tr '\0' x | base64 -w 0
# eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4

Ohne -w 0 ist die erste Zeile 76 Zeichen lang, und der Rest landet in einer zweiten Zeile. Wenn Sie Zeilen im MIME-Stil brauchen, ist der Standardumbruch genau richtig.

URL-sicheres Base64

GNU coreutils ab 8.31 enthält basenc, das Base64URL beherrscht. Das Padding bleibt dabei erhalten:

printf '%s' '<<???>>' | basenc --base64url      # PDw_Pz8-Pg==
printf '%s' 'PDw_Pz8-Pg' | basenc --base64url -d   # <<???>>

Unter macOS oder älterem Linux übersetzen Sie mit tr:

printf '%s' '<<???>>' | base64 | tr '+/' '-_' | tr -d '='   # PDw_Pz8-Pg

Zum Dekodieren brauchen Sie die umgekehrte Übersetzung und für strenge Decoder wieder das Padding:

s=PDw_Pz8-Pg
s=$(printf '%s' "$s" | tr -- '-_' '+/')
while [ $(( ${#s} % 4 )) -ne 0 ]; do s="$s="; done
printf '%s' "$s" | base64 -d        # <<???>>

Das -- verhindert, dass tr -_ als Option liest. Genau diese Umwandlung brauchen auch JWTs; der JWT-Decoder erledigt sie für Sie. Mehr dazu unter Base64 vs. Base64URL.

Dateien kodieren und dekodieren

base64 -w 0 hello.txt              # aGVsbG8K
base64 -d <<< 'aGVsbG8K' > copy.txt
base64 -d payload.b64 > payload.pdf

base64 arbeitet als Stream und liest und schreibt in Blöcken, die Dateigröße spielt also keine Rolle. So bauen Sie eine Data-URI für ein Bild:

printf 'data:image/png;base64,%s' "$(base64 -w 0 logo.png)"

Für einen HTTP-Basic-Auth-Header:

printf 'Basic %s' "$(printf '%s' 'user:pass' | base64)"   # Basic dXNlcjpwYXNz

Der Basic-Auth-Header-Generator macht dasselbe, ohne dass Ihr Passwort in der Shell-History landet.

Prüfung, Fehler und Exit-Codes

GNU base64 -d endet mit Status 1 und gibt base64: invalid input auf stderr aus, sobald es ein ungültiges Zeichen findet. Alles bis dahin Dekodierte wird trotzdem geschrieben, ein gescheitertes Dekodieren kann also eine halbe Datei hinterlassen:

printf 'aGk=!!' | base64 -d        # prints "hi", then: base64: invalid input
echo $?                            # 1 (without a pipe after it)
printf 'aGk=!!' | base64 -d -i     # hi   (garbage ignored, exit 0)

Ergebnisse mit coreutils 9.7:

EingabeErgebnis
aGkhi, Exit 0 (fehlendes Padding wird toleriert)
"aGVs\nbG8K"hello, Exit 0 (Zeilenumbrüche werden ignoriert)
aGl=hi, dann invalid input, Exit 1
ainvalid input, Exit 1
PDw_Pz8-Pg==Teilausgabe, invalid input, Exit 1

Prüfen Sie über den Exit-Status und dekodieren Sie in eine temporäre Datei, damit ein Fehler keine guten Daten überschreibt:

if printf '%s' "$b64" | base64 -d > /tmp/out.bin 2>/dev/null; then
  mv /tmp/out.bin result.bin
else
  echo "invalid Base64" >&2
fi

In einer Pipeline ist $? der Status des letzten Befehls. Ergänzen Sie set -o pipefail, wenn base64 -d nicht am Ende steht. Lässt sich ein String aus einem Log oder einer E-Mail nicht dekodieren, entfernt Base64 reparieren Anführungszeichen, Leerraum und Präfixe; die Anleitung zu Base64-Fehlern erklärt jeden einzelnen Fehler.

Weitere Tools auf der Kommandozeile

  • openssl base64 gibt es auf fast jedem System, und es verhält sich unter Linux und macOS gleich. Siehe Base64 mit OpenSSL.
  • python3 -m base64 -d file und python3 -m base64 file funktionieren, wo coreutils fehlen; die Ausgabe wird nach 76 Zeichen umgebrochen.
  • In Kubernetes ist kubectl get secret x -o jsonpath='{.data.password}' | base64 -d das übliche Muster, alternativ der Kubernetes-Secret-Decoder.

Häufige Fragen

Warum liefert echo hello | base64 ein anderes Ergebnis als Online-Tools?

echo hängt einen Zeilenumbruch an, Sie kodieren also hello\n (aGVsbG8K) statt hello (aGVsbG8=). Verwenden Sie printf '%s' hello oder echo -n hello.

Wie verhindere ich, dass base64 Zeilen umbricht?

Unter Linux mit base64 -w 0. macOS bricht standardmäßig nicht um. Für einen Befehl, der sich auf beiden Systemen gleich verhält, leiten Sie die Ausgabe durch tr -d '\n'.

Was bedeutet „base64: invalid input“?

GNU base64 -d ist auf ein Zeichen außerhalb des Alphabets oder auf kaputtes Padding gestoßen. Es gibt die bis dahin dekodierten Bytes aus, dann den Fehler, und endet mit Status 1. Typische Ursachen sind URL-sichere - und _, Anführungszeichen und data:-Präfixe.

Ist base64 -d unter macOS dasselbe wie unter Linux?

Ältere macOS-Versionen kannten nur -D (oder --decode); neuere akzeptieren auch -d. Verwenden Sie in Skripten, die auf beiden Systemen laufen müssen, --decode.

Weiterlesen