La ligne de commande communiste, le code Baudot et le comte ChatGPT

par Ploum le 2026-01-13

Il y a quelques mois, un lecteur m’a fait découvrir un incroyable jeu historico-politique entièrement réalisé en AsciiArt: « Le comte et la communiste », de Tristan Pun.

La simplicité des graphismes m’a fait plonger dans l’histoire comme dans un excellent livre. Jouant une espionne/servante, vous êtes amené à découvrir l’envers du décor d’un château aristocrate pendant la Première Guerre mondiale. De manière très intéressante pour le sous-texte sociopolitique, le temps passé dans le château est proportionnel au nombre de lessives. Car, bien qu’espionne, vous êtes avant tout une servante et il va falloir se remonter les manches et faire la lessive !

Si je vous en parle avec tant d’enthousiasme, c’est qu’à un moment du jeu vous trouvez une bande de papier contenant un message au format Baudot. Le code Baudot est l’ancêtre de l’ASCII et le premier encodage de caractère utilisé sur les télégraphes automatiques : le message est directement reçu sur des bandes de papier, à la différence du Morse qui nécessite un opérateur humain à la réception.

Une bande de papier avec un message en code Baudot (source: Ricardo Ferreira de Oliveira)
Une bande de papier avec un message en code Baudot (source: Ricardo Ferreira de Oliveira)

Dans le jeu, le message est trouvé sur une bande de papier servant de signet qui ressemble à ceci.

Une bande de papier en ASCII contenant de "o" pour les trous.
Une bande de papier en ASCII contenant de "o" pour les trous.

Sur une plaque, vous trouverez toutes les informations pour déchiffrer le code Baudot.

Capture d’écran du jeu expliquant le code Baudot.
Capture d’écran du jeu expliquant le code Baudot.

Il ne reste plus qu’à déchiffrer le message… Mais, très vite, j’ai trouvé ça laborieux. Et si je demandais à ma fidèle ligne de commande de le faire à ma place ? Après tout, la lecture de l’excellentissime « Efficient Linux at the Command Line », de Daniel J. Barret, m’a mis en confiance.

Décoder le message Baudot en ligne de commande

Attention, je vous préviens, ça va être très technique. Vous n’êtes pas obligé de vous infliger ça.

Vous êtes toujours là ? C’est parti !

Une fois le code en Asciiart copié/collé dans un fichier, on va l’afficher avec "cat". Même si ce n’est pas strictement nécessaire, je commence toujours toutes mes chaînes de pipe avec cat. Cela me semble plus clair.

Ici, la difficulté est que je veux accéder aux colonnes : je veux reconstruire un mot en prenant les premières lettres de chaque ligne, puis les secondes de chaque ligne, etc.

La commande Unix qui se rapproche le plus de cela est "cut". Cut permet de prendre le Xème caractère d’une ligne avec l’option -cX. Pour la quinzième, je fais donc "cut -c15". Tout de suite, je réalise que je vais avoir besoin d’une boucle. Considérant que les lignes font moins de 100 caractères, je peux faire un

for i in {1..100}; do" avec un "cut -c$i

Et voilà, je sais désormais isoler chaque colonne.

Dans l’asciiart, le binaire du code Baudot est représenté par des "o" et des espaces. Par soucis de clarté, je vais remplacer les espaces par des "l" (ça ressemble à un "1" binaire). La commande Unix pour faire des substitutions de caractères est "tr" (translate): tr " " l (l’espace est entre guillemets).

Toujours par souci de clarté, je vais effacer tout ce qui n’est pas un o ou un l. Tr permet d’effacer des caractères avec l’option -d et de prendre "tous les caractères sauf ceux de la liste" avec l’option -c (complémentaire). Je rajoute donc un tr -cd "ol".

La chaîne dans ma boucle ressemble donc à:

cat $1|cut -c"$i"|tr " " l|tr -cd "ol"

Problème : mes groupes de 5 lettres sont toujours verticaux !

J’ai tenté l’approche de supprimer les retours à la ligne avec tr -d "\n", mais cela produit des résultats bizarres, surtout que le dernier retour à la ligne est lui aussi supprimé.

Du coup, la commande qui me semble tout indiquée pour faire cela est le contraire de "cut" : "paste". Mais, essayez de lancer la chaîne dans "paste" : rien ne se passe !

Et pour cause : paste est initialement conçu pour joindre chaque ligne de plusieurs fichiers. Ici, il n’y a qu’un seul fichier : le flux d’entrée. Paste ne peux donc rien lui joindre.

Heureusement, l’option "-s" permet de dire à paste de tout mettre sur une seule ligne. Je suis complètement passé à côté pour une raison très simple : la page man de paste est incompréhensible.

-s, --serial
copier un fichier à la fois au lieu de le faire en parallèle

Je défie quiconque de voir le rapport entre la page de man et la fonction réelle. J’ai heureusement eu l’intuition de tester avec "tldr" au lieu de man.

Join all the lines into a single line, using TAB as delimiter:
paste -s path/to/file

Avouez que c’est déjà beaucoup plus clair !

Un p’tit test me révèle que c’est presque bon. Tout est sur une ligne. Sauf qu’il y’a désormais des TAB entre chaque lettre. On pourrait les enlever avec tr. Ou simplement dire à paste de ne pas les mettre en utilisant à la place un séparateur nul:

cat $1|cut -c"$i"|tr " " l|tr -cd "ol"|paste -sd "\0"

Ma boucle for m’affiche désormais chaque lettre sur une ligne. Il ne me reste qu’à traduire le code Baudot.

Je peux, par exemple, rajouter un pipe vers "sed s/llloo/a/" pour remplacer les lettres a. Et un pipe vers un nouveau sed pour la lettre b et ainsi de suite. Ça fonctionne, mais c’est moche et très lent (chaque sed lançant son propre process).

Lorsqu’on a beaucoup de règles sed, autant les mettre dans un fichier baudot.sed qui contient les commandes sed, une par ligne :

s/llloo/a/
s/oollo/b/
s/loool/c/
...

Je peux appeler ces règles avec "sed -f baudot.sed".

Le code Baudot a une subtilité : y’a un code qui permet de passer en mode "caractère spécial". Je ne prends pas la tête, je me contente de remplacer ce code par "<" et le code pour revenir en mode normal par ">" (ces deux caractères n’existant pas dans le code Baudot). De cette manière, je sais que toute lettre entre < > n’est pas vraiment la lettre, mais le symbole correspondant. Un <m> est en réalité un ".". Également, il y a de nombreux espaces avant et après les messages, qui ont été convertis en autant de "l". Là, j’ai fait un bon gros hack. Au lieu de mettre un "l" normal dans le code Baudot, j’ai mis un L majuscule. Ensuite, à la toute fin, je supprime les "l" restant avec une règle globale : "s/l//g" (le "g" indique de changer tous les l sur une ligne, même s’il y’en a plusieurs). Puis, je remets en minuscule le "L" avec "s/L/l". Oui, c’est un bon gros hack. Ça fait l’affaire.

Mon fichier baudot.sed ressemble alors à ça :

s/ooloo/</
s/lloll/ /
s/ooooo/>/
s/llloo/a/
s/oollo/b/
s/loool/c/
s/lollo/d/
s/llllo/e/
s/loolo/f/
s/oolol/g/
s/ololl/h/
s/llool/i/
s/loloo/j/
s/loooo/k/
s/ollol/L/
s/oooll/m/
s/looll/n/
s/oolll/o/
s/oolll/p/
s/olooo/q/
s/lolol/r/
s/llolo/s/
s/ollll/t/
s/llooo/u/
s/ooool/v/
s/olloo/w/
s/ooolo/x/
s/ololo/y/
s/olllo/z/
s/l//g
s/L/l/g

Mon message est décodé. Mais, bien entendu, il s’affiche verticalement.

Ça ne vous rappelle rien ?

Un bon vieux paste -sd "\0" remet tout à l’endroit (et cette fois-ci, je n’ai pas eu à chercher).

Dans le jeu, le seul symbole utilisé sera le point, qui est ici devenu un "<m>" ou "<m" s’il est à la fin du message. Soyons propres jusqu’au bout et rajoutons deux petits sed. On pourrait également faire un autre fichier sed avec tous les caractères, mais le jeu ne comporte finalement que deux messages.

Dommage, là j’étais chaud pour plus.

Mon script final est donc :

#!/bin/bash
for i in {1..100}; do
	cat $1|cut -c"$i"|tr " " l|tr -cd "ol"|paste -sd "\0"
done|sed -f baudot.sed|paste -sd "\0"|sed "s/<m>/./"|sed "s/<m/./"

Avec le recul, ce script est beaucoup plus simple et efficace qu’un script Python. Le script Python prendrait des dizaines de lignes et agirait sur une matrice de caractères. Les outils Unix, eux, agissent sur des flux de texte. J’y trouve une certaine élégance, un plaisir particulier. Le tout m’a pris environ 30 minutes, dont une bonne partie sur l’erreur de "tr -d \n".

Demander à ChatGPT de décoder le message Baudot

Comme mon compte Kagi me donne désormais accès à ChatGPT, je me suis dit que j’allais faire l’expérience de lui demander de résoudre le même problème que moi. Histoire de comprendre ce qu’est le « Vibe coding ».

Au départ, ChatGPT est perdu. Il ne sait clairement pas traduire les messages, m’assène de longues tables de soi-disant code Baudot (qui sont parfois correctes, mais pas toujours) et me raconte l’histoire de ce code (qui est généralement correcte, mais que je n’ai pas demandée). C’est verbeux, je dois lui dire plusieurs fois de faire cours et d’être efficace.

Je lui demande de me faire un script bash. Ses premières tentatives sont extrêmement longues et incompréhensibles. Il semble beaucoup aimer les scripts awk à rallonge.

Persévérant, je demande à ChatGPT de ne plus utiliser awk et je lui explicite chaque étape l’une après l’autre: je lui dit qu’il faut parcourir chaque colonne, la redresser, la convertir, etc.

Logiquement, il arrive à un résultat très similaire au mien. Il choisit d’utiliser "tr -d \n" pour supprimer les fins de ligne, mais, comme je l’ai dit, ça ne fonctionne pas correctement. Je lui passe, car je n’ai moi‑même pas compris l’erreur.

Je constate cependant une amélioration intéressante : là où j’ai demandé les 100 premières colonnes, chatGPT mesure la longueur avec :

for i in $(seq $(head -1 $1|wc -c)); do

Concrètement, il prend la première ligne avec "head -1", compte les caractères avec "wc -c" et construit une séquence de 1 jusqu’a ce nombre avec "seq".

C’est une excellente idée si on considère que la première ligne est représentative des autres. Une fois le "redressement" en place (il m’a fallu des dizaines de prompts et d’exemples pour arriver à lui expliquer, à chaque fois il prétend qu’il a compris et c’est faux), je lui demande de traduire en utilisant le code Baudot.

Au lieu de ma solution avec "sed", il fait une fonction bash "baudot_to_letter" qui est un gros case:

baudot_to_letter() {
  case $1 in
    00000) echo " " ;;
    00001) echo "E" ;;
    00010) echo "A" ;;

Fait amusant, les caractères ne sont pas en ordre alphabétique, mais dans l’ordre binaire de la représentation Baudot. Pourquoi pas ?

Je valide cette solution même si je préfère le sed parce que je n’avais pas envie de faire du bash mais utiliser les outils Unix. Je lui ai dit plusieurs fois que je voulais une commande Unix, pas un script bash avec plusieurs fonctions. Mais je lui laisse, car, au fond, sa solution est pertinente.

Maintenant que toutes les étapes ont été décrites, je teste son code final. Qui ne fonctionne pas, produisant une erreur bash. Je lui demande une nouvelle version en lui copiant-collant l’erreur. Après plusieurs itérations de ce type, j’ai enfin un script qui fonctionne et me renvoie la traduction du message suivante :

LLECJGCISTGCIUMCEISJEISKN CT UIXV SJECUZUCEXV

Le nombre de lettres n’est même pas correct. Je n’ai évidemment pas envie de débugger le truc. Je demande à lors à ChatGPT de lancer le script lui-même pour me donner la traduction :

ChatGPT me dit que le message traduit est "ECHOES OF THE PAST". Il est très fier, car c’est un message cohérent. Sauf que le jeu est en français…
ChatGPT me dit que le message traduit est "ECHOES OF THE PAST". Il est très fier, car c’est un message cohérent. Sauf que le jeu est en français…

À ce point de l’histoire, j’ai, montre en main, passé plus de temps à tenter d’utiliser ChatGPT que je n’en ai mis pour écrire mon propre script, certes imparfait, mais fonctionnel. Je me retrouve à faire des copier-coller incessants entre ChatGPT et mon terminal, à tenter de négocier des changements et déboguer du code que je n’ai pas écrit.

Et encore, pour ChatGPT, j’ai nettoyé le message en enlevant tout ce qui n’est pas le code Baudot. Mon propre script est beaucoup plus robuste. J’en ai marre et j’abandonne.

Moralité

ChatGPT n’est impressionnant que par sa capacité à converser, à prétendre. Oui, il peut parfois donner des idées. Il a par exemple amélioré la première ligne de mon script que j’avais bâclée.

Mais il faut avoir du temps à perdre. À ce moment-là, autant replonger dans un bon livre dont on sait que la majeure partie des idées sont bonnes.

ChatGPT peut être utile pour brainstormer à condition d’être soi-même fin connaisseur du domaine et très critique avec tout ce qui sort. C’est dire la débauche d’énergie pour finalement très peu de choses.

Vous croyez être plus efficace en utilisant l’AI, car vous passez moins de temps à « penser ». Mais les études semblent montrer qu’en réalité, vous êtes plus lent. Avec ChatGPT, on est tout le temps "occupé". On ne s’arrête jamais pour réfléchir à son problème, pour lire différentes ressources.

Et lorsque ChatGPT vous fait vraiment gagner du temps, c’est peut-être parce qu’il s’agit d’un domaine où vous n’êtes pas vraiment compétent. En ce qui concerne la ligne de commande, je ne peux que répéter ma suggestion de lire « Efficient Linux at the Command Line ». Vraiment !

Comme le rappelle très bien Cal Newport: qui a le plus intérêt à ce que vous soyez un ouvrier incompétent qui se contente de pousser aveuglément sur les boutons d’une machine au lieu de faire fonctionner son cerveau ?

Peut-être que passer quelques heures à espionner les aristocrates en étant obligé de faire des lessives vous fera réfléchir à ce sujet. En tout cas, ça en vaut la peine !

Bon amusement, bonnes réflexions et… bonnes lessives !

À propos de l’auteur :

Je suis Ploum et je viens de publier Bikepunk, une fable écolo-cycliste entièrement tapée sur une machine à écrire mécanique. Pour me soutenir, achetez mes livres (si possible chez votre libraire) !

Recevez directement par mail mes écrits en français et en anglais. Votre adresse ne sera jamais partagée. Vous pouvez également utiliser mon flux RSS francophone ou le flux RSS complet.


Permalinks:
https://ploum.net/2026-01-13-ligne-de-commande-baudot-chatgpt.html
gemini://ploum.net/2026-01-13-ligne-de-commande-baudot-chatgpt.gmi