Charger un fichier
  1. base64hub
  2. Base64 dans le code
  3. Bash
Code

Base64 en Bash

C’est la commande base64 qui fait le travail ; Bash ne fait que lui transmettre les données. GNU coreutils sous Linux et l’outil BSD de macOS n’acceptent pas les mêmes options. Les sorties Linux ci-dessous proviennent de GNU coreutils 9.7.

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âcheGNU coreutils (Linux)macOS
Décoder-d, --decode-D, --decode (aussi -d dans les versions récentes)
Pas de retour à la ligne-w 0par défaut
Couper à N caractères-w N (76 par défaut)-b N
Fichier d’entréebase64 filebase64 -i file ou base64 < file
Fichier de sortieredirection >-o file ou redirection
Ignorer les déchets au décodage-i, --ignore-garbagenon 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éeRésultat
aGkhi, code 0 (remplissage manquant toléré)
"aGVs\nbG8K"hello, code 0 (sauts de ligne ignorés)
aGl=hi, puis invalid input, code 1
ainvalid 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 base64 existe 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 file et python3 -m base64 file fonctionnent là où coreutils manque ; la sortie est coupée à 76 caractères.
  • Avec Kubernetes, kubectl get secret x -o jsonpath='{.data.password}' | base64 -d est 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.

Continuer la lecture