Les jeux de caractères sous Linux

Retour à la page Systèmes

Motivation

Souvent le terminal n'affiche pas les caractères attendus.
Cette page présente quelques recettes (non-exhaustives!) pour traquer la source du problème et tenter d'en isoler les acteurs.
Les quelques caractères qu'elle contient s'afficheront bien sur tout navigateur internet acceptant l'UTF8 (i.e. tout navigateur récent).

Diagnostic

On peut commencer par tester un cas de base avec un minimun d'intervenants:

Si les manipulations précédentes ne résolvent pas le problème, chercher la nature des caractères indésirables:

On peut souvent reconnaître pifométriquement le type de problème (s'affichera bien en UTF-8):

Conversion de caractères

Linux propose la commande «iconv» pour lire des caractères et les convertir d'un jeu de caractères à un autre.

Ainsi, pour afficher un fichier codé en latin-1 dans un terminal réglé pour UTF-8:

iconv <fichier-lat1 >fichier-utf8         #Conversion de fichier
cat fichier-lat1 | iconv -f ISO-8859-1 -t UTF-8 #Conversion juste pour l'affichage

Comme les «pipes» de Linux n'altèrent pas les octets transmis, on peut récupérer leur valeur hexa à la sortie.
Ainsi, pour voir le numéro unicode d'un caractère � copié-collé dans un terminal UTF-8:

echo -n � | iconv -f utf-8 -t utf-32be | hexdump -C
00000000  00 00 ff fd                                       |....|

Explication: le echo -n n'ajoute pas de caractère superflu comme un retour à la ligne, le codage utf-32be est pratiquement le numéro unicode du caractère sur 32 bits (le «be» pour «big endian» met les octets par poids décroissant), et le hexdump traduit ces 32 bits en chiffres hexadécimaux: 0xFFFD.

Le codage UTF-8

Le terme UTF-8 revenant souvent à propos des chaînes de caractères, un peu de vulgarisation ne devrait pas faire de mal. Des explications plus poussées sont dans «man utf-8», «man iconv», «man charsets», et «man unicode»:

Le standard UNICODE donne (en simplifiant) un numéro à chaque caractère de chaque langue. Sans imposer de codage particulier, il reprend, pour la compatibilité, les 128 numéros ASCII (beaucoup d'explications sont ici );

Arrive la question du codage: les numéros UNICODE prennent souvent 2 voire 4 octets en binaire; mais utiliser 2 ou 4 octets par caractère dans des langues où les caractères ASCII dominent serait du gaspillage.

D'où l'idée du codage UTF-8 (Unicode Transformation Format): il écrit les numéros ASCII 0-127 sur un seul octet, et les suivants (>=128) à l'aide d'octets de «prolongation». Voici ce qui a été retenu:

Ce codage s’est imposé rapidement par ses bonnes qualités techniques et pratiques, dont en particulier:

L'inconvénient principal est que la longueur d'une chaîne, en caractères, n'est plus synonyme de sa taille en octets: il faut décoder pour la connaître.

Pour aller plus loin

L'article pourrait se prolonger indéfiniment. Quelques guides complémentaires (en anglais):

Dernière modification: 18 février 2017