Aller au contenu principal

ASCII, Unicode et UTF-8 : quelles différences ?

Trois noms qu'on emploie souvent l'un pour l'autre, alors qu'ils désignent trois choses distinctes. Voici ce que chacun recouvre, et comment ils s'articulent.

En résumé

  • ASCII est un jeu de 128 caractères, numérotés de 0 à 127. Il couvre l'alphabet anglais, les chiffres, la ponctuation et des codes de contrôle. Aucun accent.
  • Unicode est un catalogue universel : il attribue un numéro, appelé point de code, à chaque caractère de chaque écriture. Ce n'est pas un encodage, seulement une liste.
  • UTF-8 est une façon d'écrire ces numéros sous forme d'octets. C'est l'encodage le plus répandu, et il est rétrocompatible avec l'ascii.

ASCII : 128 caractères sur 7 bits

L'ascii, publié pour la première fois en 1963 puis fixé dans sa forme actuelle à la fin des années 1960, associe un nombre à chacun de ses 128 caractères. La lettre A porte le code 65, le chiffre 0 porte le code 48, l'espace porte le code 32. Sept bits suffisent, puisque 2⁷ vaut exactement 128.

Ces 128 codes se répartissent en deux familles. Les codes 0 à 31, plus le code 127, sont des caractères de contrôle : ils ne s'affichent pas, ils commandent. Les codes 32 à 126 sont les caractères imprimables : espace, ponctuation, chiffres, majuscules et minuscules de l'alphabet latin sans accent. Vous pouvez parcourir l'ensemble sur la table ascii de 0 à 127.

Un octet compte huit bits. Comme l'ascii n'en utilise que sept, le huitième restait libre. Il a d'abord servi de bit de parité pour détecter les erreurs de transmission. Puis, quand ce contrôle est devenu superflu, il est apparu comme une réserve de 128 codes supplémentaires. Toute la suite de l'histoire découle de là.

Le problème des accents et les pages de code

L'ascii ne connaît ni é, ni ç, ni ñ, ni ß. Chaque pays a donc rempli les codes 128 à 255 à sa façon, en créant ce qu'on appelle des pages de code. ISO-8859-1, dite Latin-1, sert les langues d'Europe occidentale. Windows-1252, souvent appelée « ANSI », en est la variante Microsoft, avec des caractères typographiques supplémentaires aux positions 128 à 159. CP437, la page OEM des PC IBM, privilégiait quant à elle les caractères semi-graphiques de tracé de cadres.

Le résultat était ingérable. Le même octet 233 valait é en Latin-1, mais un tout autre caractère dans une page de code cyrillique ou grecque. Un fichier ne portait pas en lui l'indication de sa page de code : il fallait la deviner ou la transmettre à côté. Et surtout, aucune page de code ne permettait de mélanger du français, du russe et du japonais dans un même document, puisque toutes se partageaient les mêmes 128 positions.

Unicode : un point de code par caractère

Unicode répond à ce désordre par une idée simple : un seul catalogue mondial, où chaque caractère reçoit un numéro unique et définitif, appelé point de code. On l'écrit sous la forme U+ suivi de la valeur en hexadécimal : la lettre A est U+0041, la lettre é est U+00E9, le signe euro est U+20AC.

Les 128 premiers points de code, de U+0000 à U+007F, sont exactement ceux de l'ascii, dans le même ordre. Unicode n'a rien réinventé sur cette plage : A vaut 65 en ascii et U+0041 en Unicode, soit 65 écrit en hexadécimal. Les 256 premiers reprennent de la même manière ISO-8859-1.

Au-delà, le répertoire est immense : plus de 150 000 caractères sont aujourd'hui codés, et l'espace disponible va jusqu'à U+10FFFF. Alphabets latin, grec, cyrillique, arabe, hébreu, écritures indiennes, idéogrammes chinois, japonais et coréens, symboles mathématiques, notation musicale, émojis : tout tient dans le même catalogue.

Point essentiel, et source de la plupart des malentendus : Unicode n'est pas un encodage. Il dit que é porte le numéro 233. Il ne dit pas comment écrire 233 dans un fichier. Cette seconde question relève des formats de transformation : UTF-8, UTF-16 et UTF-32.

UTF-8 : l'encodage à longueur variable

UTF-8 traduit un point de code en une suite de un à quatre octets. Sa règle fondatrice est la rétrocompatibilité : les points de code U+0000 à U+007F, c'est-à-dire l'ascii, s'écrivent sur un seul octet, dont la valeur est identique au code ascii. Les caractères suivants s'écrivent sur deux, trois ou quatre octets, tous supérieurs à 127.

Plage de points de codeOctetsContenu principal
U+0000 à U+007F1Les 128 caractères de l'ascii
U+0080 à U+07FF2Latin accentué, grec, cyrillique, hébreu, arabe
U+0800 à U+FFFF3Idéogrammes chinois, japonais et coréens, symboles courants
U+10000 à U+10FFFF4Émojis, écritures anciennes, caractères rares

Une conséquence importante en découle : tout fichier ascii est déjà un fichier UTF-8 valide. Aucune conversion n'est nécessaire, aucun octet ne change. Un programme écrit avant Unicode qui lit de l'UTF-8 anglais fonctionne sans modification. C'est cette compatibilité qui explique l'adoption massive d'UTF-8 sur le Web, où il encode aujourd'hui la quasi-totalité des pages.

Le prix à payer est que le texte accentué occupe plus de place : é tient sur deux octets au lieu d'un en Latin-1. Pour un texte français, la différence reste marginale. En contrepartie, la structure des octets rend l'encodage robuste : on distingue immédiatement le premier octet d'un caractère de ses octets de continuation, ce qui permet de se resynchroniser au milieu d'un flux et de détecter une séquence invalide.

UTF-8, UTF-16, UTF-32 : lequel choisir

Les trois encodent le même catalogue Unicode. Ils diffèrent par la façon de découper les points de code en octets, et donc par leurs compromis.

EncodageTaille par caractèreCompatible asciiUsage typique
UTF-81 à 4 octetsOuiWeb, fichiers, bases de données, échanges de données
UTF-162 ou 4 octetsNonChaînes en mémoire : Windows, Java, JavaScript, .NET
UTF-324 octetsNonTraitements internes où l'accès direct par indice prime

Pour un fichier, une page web, une API ou une base de données, la réponse est UTF-8 sans hésiter. UTF-16 se rencontre surtout à l'intérieur des programmes, parce que plusieurs plateformes historiques ont adopté ce format pour représenter leurs chaînes en mémoire. UTF-32, qui consacre quatre octets à chaque caractère, gaspille beaucoup d'espace et ne s'utilise que dans des traitements internes très particuliers.

Contrairement à une idée reçue, aucun de ces encodages ne garantit qu'un caractère affiché à l'écran corresponde à une seule unité de stockage. Un émoji peut occuper quatre octets en UTF-8 comme en UTF-32, et une lettre accentuée peut s'écrire soit comme un point de code unique, soit comme une lettre suivie d'un accent combinant.

Pourquoi je vois « é » à la place de « é »

Ce charabia porte un nom, emprunté au japonais : le mojibake. Il ne signale presque jamais un fichier abîmé, mais un malentendu sur l'encodage : le texte a été écrit avec une table et relu avec une autre.

Le cas le plus fréquent se démonte octet par octet. La lettre é porte le point de code U+00E9. En UTF-8, elle s'écrit sur deux octets : C3 et A9 en hexadécimal, soit 195 et 169 en décimal. Si un logiciel lit ces deux octets en croyant avoir affaire à du Windows-1252, il les traite séparément : l'octet 195 s'y affiche Ã, l'octet 169 s'y affiche ©. À l'écran, é devient donc é. De la même manière, ç devient ç, è devient è et ô devient ô.

Le phénomène inverse existe aussi. Un texte accentué écrit en Windows-1252 puis relu en UTF-8 présente des octets isolés qui ne forment aucune séquence valide ; l'éditeur les remplace alors par le caractère de remplacement �, ou par un point d'interrogation.

La correction tient en trois gestes. D'abord, identifier l'encodage réel du fichier : la plupart des éditeurs de texte permettent de le rouvrir en imposant une table précise. Ensuite, l'enregistrer en UTF-8, de préférence sans marque d'ordre des octets (le BOM), qui perturbe certains outils. Enfin, déclarer l'encodage partout où il doit l'être : la balise <meta charset="utf-8"> dans une page HTML, l'en-tête Content-Type côté serveur, le jeu de caractères de la base de données et celui de la connexion. Une seule déclaration oubliée suffit à faire réapparaître les é.

Si vous ne pouvez pas corriger la source, l'échappement HTML dépanne : écrire l'entité correspondante plutôt que le caractère lui-même met le texte à l'abri de l'encodage du fichier.

Ce qu'il faut retenir

ASCII, Unicode et UTF-8 ne sont pas trois concurrents : ce sont trois étages du même édifice. L'ascii a défini 128 caractères et leurs numéros. Unicode a repris ces 128 numéros à l'identique et a étendu le catalogue au monde entier. UTF-8 a trouvé le moyen d'écrire ce catalogue en octets sans rien casser de l'existant.

En pratique, trois réflexes suffisent. Employez UTF-8 partout, sans exception. Déclarez-le explicitement dans vos fichiers, vos pages et vos bases. Et devant un affichage douteux, cherchez d'abord quelle table a servi à écrire, puis quelle table a servi à lire : l'écart entre les deux explique presque toujours le problème.

Pour aller plus loin, consultez la liste complète des tables ascii ou les outils de conversion entre ascii, binaire, octal, décimal et hexadécimal.