Encoder et décoder une chaîne
printf '%s' 'héllo wörld' | base64 # aMOpbGxvIHfDtnJsZA==
printf '%s' 'aMOpbGxvIHfDtnJsZA==' | base64 -d # héllo wörld
base64 encode des octets : le résultat dépend donc de l’encodage de votre terminal. Sur n’importe quelle installation Linux ou macOS récente, c’est UTF-8.
L’erreur classique, c’est echo, qui ajoute un saut de ligne :
echo 'héllo wörld' | base64 # aMOpbGxvIHfDtnJsZAo= (note the "o=")
echo -n hi | base64 # aGk=
echo -n fonctionne en Bash mais pas dans tous les sh ; printf '%s' est portable. Une here-string (base64 <<< "text") ajoute elle aussi un saut de ligne. Si quelqu’un vous envoie du Base64 qui se termine par Cg== ou o=, il contient probablement un saut de ligne final ; collez-le dans le décodeur Base64 pour le vérifier.
Options GNU (Linux) et BSD (macOS)
| Tâche | GNU coreutils (Linux) | macOS |
|---|---|---|
| Décoder | -d, --decode | -D, --decode (aussi -d dans les versions récentes) |
| Pas de retour à la ligne | -w 0 | par défaut |
| Couper à N caractères | -w N (76 par défaut) | -b N |
| Fichier d’entrée | base64 file | base64 -i file ou base64 < file |
| Fichier de sortie | redirection > | -o file ou redirection |
| Ignorer les déchets au décodage | -i, --ignore-garbage | non disponible |
Les deux options -i n’ont pas le même sens : sous macOS, elle désigne le fichier d’entrée, sous Linux, elle ignore les caractères parasites. Un script portable lit sur stdin et écrit sur stdout :
base64 < in.bin | tr -d '\n' > out.b64 # same output on Linux and macOS
base64 --decode < out.b64 > in-copy.bin
GNU base64 coupe les lignes à 76 caractères par défaut, ce qui casse les en-têtes et les variables d’environnement :
head -c 60 /dev/zero | tr '\0' x | base64 -w 0
# eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4
Sans -w 0, la première ligne fait 76 caractères et le reste passe à la ligne suivante. Si vous voulez des lignes au format MIME, le découpage par défaut est justement ce qu’il vous faut.
Base64 URL-safe
GNU coreutils 8.31 et versions ultérieures fournissent basenc, qui prend en charge Base64URL. Il conserve le remplissage :
printf '%s' '<<???>>' | basenc --base64url # PDw_Pz8-Pg==
printf '%s' 'PDw_Pz8-Pg' | basenc --base64url -d # <<???>>
Sous macOS ou sur un Linux plus ancien, convertissez avec tr :
printf '%s' '<<???>>' | base64 | tr '+/' '-_' | tr -d '=' # PDw_Pz8-Pg
Le décodage demande la conversion inverse et, pour les décodeurs stricts, le rétablissement du remplissage :
s=PDw_Pz8-Pg
s=$(printf '%s' "$s" | tr -- '-_' '+/')
while [ $(( ${#s} % 4 )) -ne 0 ]; do s="$s="; done
printf '%s' "$s" | base64 -d # <<???>>
Le -- empêche tr d’interpréter -_ comme une option. C’est la même transformation que celle qu’exigent les JWT ; le décodeur JWT s’en charge pour vous. Plus de détails dans Base64 ou Base64URL.
Encoder et décoder des fichiers
base64 -w 0 hello.txt # aGVsbG8K
base64 -d <<< 'aGVsbG8K' > copy.txt
base64 -d payload.b64 > payload.pdf
base64 travaille en flux : la taille du fichier n’a pas d’importance, il lit et écrit par blocs. Pour construire une data URI à partir d’une image :
printf 'data:image/png;base64,%s' "$(base64 -w 0 logo.png)"
Pour un en-tête HTTP Basic Auth :
printf 'Basic %s' "$(printf '%s' 'user:pass' | base64)" # Basic dXNlcjpwYXNz
Le générateur d’en-tête Basic Auth fait la même chose sans laisser votre mot de passe dans l’historique du shell.
Validation, erreurs et codes de sortie
GNU base64 -d se termine avec le code 1 et affiche base64: invalid input sur stderr quand il trouve un caractère invalide. Il écrit malgré tout tout ce qu’il a décodé jusque-là : un décodage raté peut donc laisser un fichier partiel derrière lui.
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)
Résultats avec coreutils 9.7 :
| Entrée | Résultat |
|---|---|
aGk | hi, code 0 (remplissage manquant toléré) |
"aGVs\nbG8K" | hello, code 0 (sauts de ligne ignorés) |
aGl= | hi, puis invalid input, code 1 |
a | invalid input, code 1 |
PDw_Pz8-Pg== | sortie partielle, invalid input, code 1 |
Servez-vous du code de sortie pour valider, et décodez vers un fichier temporaire pour qu’un échec n’écrase pas des données correctes :
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
Dans un pipeline, $? est le code de la dernière commande. Ajoutez set -o pipefail si base64 -d n’est pas en dernière position. Quand une chaîne issue d’un log ou d’un e-mail refuse de se décoder, Réparer Base64 retire les guillemets, les espaces et les préfixes ; le guide des erreurs explique chaque échec.
Autres outils en ligne de commande
openssl base64existe sur presque tous les systèmes et se comporte de la même façon sous Linux et macOS. Voir Base64 avec OpenSSL.python3 -m base64 -d fileetpython3 -m base64 filefonctionnent là où coreutils manque ; la sortie est coupée à 76 caractères.- Avec Kubernetes,
kubectl get secret x -o jsonpath='{.data.password}' | base64 -dest le réflexe habituel, sinon utilisez le décodeur de secrets Kubernetes.
FAQ
Pourquoi echo hello | base64 donne-t-il un autre résultat que les outils en ligne ?
echo ajoute un saut de ligne : vous encodez hello\n (aGVsbG8K) au lieu de hello (aGVsbG8=). Utilisez printf '%s' hello ou echo -n hello.
Comment empêcher base64 de couper les lignes ?
Sous Linux, base64 -w 0. macOS ne coupe pas par défaut. Pour une commande qui se comporte de la même façon sur les deux, passez la sortie dans tr -d '\n'.
Que signifie « base64: invalid input » ?
GNU base64 -d a rencontré un caractère hors de l’alphabet ou un remplissage cassé. Il affiche les octets décodés jusque-là, puis l’erreur, et se termine avec le code 1. Les coupables habituels sont les - et _ du format URL-safe, les guillemets et les préfixes data:.
base64 -d sous macOS est-il identique à celui de Linux ?
Les anciennes versions de macOS ne connaissaient que -D (ou --decode) ; les versions récentes acceptent aussi -d. Utilisez --decode dans les scripts qui doivent tourner sur les deux.