L'encodage de caracteres explique : de l'ASCII a l'UTF-8
Pourquoi votre texte se transforme parfois en points d'interrogation et symboles bizarres. Guide pratique de l'encodage de caracteres.
Tu ouvres un fichier et tu vois ü au lieu de u. Ou une base de donnees renvoie ???? la ou il devrait y avoir un nom. Ou un e-mail arrive avec =?UTF-8?B? eparpille dans l'objet.
Bienvenue dans le merveilleux monde des problemes d'encodage de caracteres.
Un peu d'histoire
Les ordinateurs stockent des nombres, pas des lettres. Donc quelqu'un a du decider quel nombre correspond a quelle lettre. Dans les annees 1960, l'ASCII a attribue les numeros 0-127 aux lettres anglaises, chiffres et symboles de base. La lettre "A" est 65. Un espace est 32. Simple.
Mais l'ASCII ne couvre que 128 caracteres. Ca marche pour l'anglais. Ca ne marche pas pour les accents francais, les kanji japonais, l'ecriture arabe, ou les milliers d'autres caracteres que les humains utilisent reellement.
Le chaos avant Unicode
Differentes regions ont invente leurs propres encodages. L'Europe de l'Ouest a eu ISO-8859-1. Le Japon a eu Shift-JIS. La Russie a eu KOI8-R. La Chine a eu GB2312. Chacun fonctionnait bien dans son propre ecosysteme. Des qu'on les melangeait, tout cassait.
Un fichier sauvegarde dans un encodage et ouvert avec un autre donne du mojibake -- ce fatras de caracteres errones que tu as probablement deja vu. cafe devient café quand un fichier UTF-8 est lu en ISO-8859-1.
Unicode a resolu le probleme de correspondance
Unicode a donne a chaque caractere un numero unique (appele "point de code"). Le A latin est U+0041. Le bonhomme de neige est U+2603. Chaque emoji, chaque systeme d'ecriture, chaque symbole mathematique obtient son propre point de code. Plus de 150 000 caracteres et ca augmente.
Mais Unicode n'est que la correspondance. Il ne dit pas comment stocker ces nombres en octets. C'est le role de l'encodage.
UTF-8 : l'encodage qui a gagne
UTF-8 est la facon dont la majeure partie d'Internet stocke le texte Unicode. Son astuce cle : il utilise un nombre variable d'octets par caractere.
- Caracteres ASCII (lettres anglaises, chiffres) : 1 octet chacun
- Caracteres accentues europeens : 2 octets chacun
- Caracteres asiatiques (CJK) : 3 octets chacun
- Emojis et symboles rares : 4 octets chacun
Cela signifie que le texte anglais en UTF-8 est identique a l'ASCII. Les anciens systemes ne cassent pas. Mais tu peux quand meme representer n'importe quel caractere au monde.
Aujourd'hui, plus de 98% des sites web utilisent UTF-8. La guerre des encodages est terminee, et UTF-8 a gagne.
UTF-8 vs UTF-16 vs UTF-32
UTF-8 : Largeur variable (1-4 octets). Efficace pour le texte majoritairement anglais. Standard du web.
UTF-16 : Largeur variable (2 ou 4 octets). Utilise en interne par JavaScript, Java et Windows. Chaque caractere fait au minimum 2 octets, donc moins efficace pour le texte ASCII.
UTF-32 : Largeur fixe (4 octets par caractere). Simple mais gaspilleur. Rarement utilise pour le stockage ou la transmission.
Le string.length de JavaScript compte les unites de code UTF-16, pas les caracteres. C'est pourquoi "😀".length renvoie 2, pas 1.
Quand l'encodage deraille
Lire un fichier avec le mauvais encodage. Les octets sont corrects, mais ils sont mal interpretes. Solution : specifier le bon encodage a l'ouverture.
Desaccord de jeu de caracteres de base de donnees. Ton app envoie de l'UTF-8, mais la colonne de la base est configuree en latin1. Les caracteres hors ASCII sont corrompus. Solution : configurer ta base en utf8mb4 (pas juste utf8 en MySQL, qui ne gere que les caracteres de 3 octets).
En-tete charset HTTP manquant. Si le serveur n'envoie pas Content-Type: text/html; charset=utf-8, les navigateurs doivent deviner. Parfois ils se trompent.
Conseils pratiques
Utilise toujours UTF-8. Sauf raison tres specifique, UTF-8 est le bon choix pour tout.
Declare ton encodage explicitement. En HTML : <meta charset="utf-8">. En HTTP : Content-Type: text/html; charset=utf-8. Ne laisse pas les systemes deviner.
Attention a la longueur des chaines. En JavaScript, le comptage de caracteres devient delicat avec les emojis et les caracteres combinants. Utilise Array.from(str).length ou l'API Intl.Segmenter pour des comptages precis.
Attention au BOM. Le Byte Order Mark (U+FEFF) apparait parfois au debut des fichiers UTF-8. Il est invisible mais peut casser des parseurs. Certains editeurs l'ajoutent silencieusement.
L'encodage de caracteres n'est pas passionnant, mais le comprendre fait gagner des heures de debogage. Utilise UTF-8 partout, declare-le explicitement, et quand tu verras du texte corrompu, tu sauras exactement ou chercher.