Comment on est arrivé à UTF-8
1. Résumé essentiel
UTF-8 est l'acronyme de Unicode Transformation Format 8‑bit.
UTF-8 est né pour résoudre trois problèmes majeurs :
- ASCII trop limité : seulement 128 caractères.
- Extensions ISO-8859 incompatibles : Latin-1, Latin-9, CP1252, etc.
- Besoin d’un système unique pour toutes les langues : Unicode (1991).
UTF-8 encode Unicode sans casser l’ASCII, avec une longueur variable.
2. Avant UTF-8 : le chaos des codages
2.1 ASCII (années 1960)
ASCII utilise 7 bits, soit 128 caractères. Suffisant pour l’anglais, mais impossible d’écrire des lettres accentuées comme « é », « ç », « ü ». Le 8e bit est au départ inutilisé.
Exemple :
A = 1000001₂ (65 en décimal)
2.2 Extensions 8 bits : ISO-8859, CP1252, etc.
Pour ajouter des accents, on utilise le 8e bit, ce qui donne 256 positions possibles. Chaque région définit sa propre table :
- ISO-8859-1 (Latin-1)
- ISO-8859-15 (Latin-9, avec le symbole €)
- Windows-1252 (CP1252)
- MacRoman, et d’autres encore.
Problèmes :
- Impossible d’écrire du français et du japonais dans le même fichier.
- Un même octet peut représenter un caractère différent selon la table.
- Affichages « pourris » quand on lit un fichier avec le mauvais codage.
Exemple :
Fichier CP1252 lu comme ISO-8859-1 → "é" au lieu de "é".
3. Unicode : unifier le monde (à partir de 1991)
Unicode introduit l’idée de point de code : chaque caractère reçoit un numéro unique, de la forme
U+XXXX. Unicode sépare :
- le caractère abstrait,
- son point de code (ex. U+00E9 pour « é »),
- la façon de l’encoder (UTF-8, UTF-16, UTF-32).
Problème restant : comment encoder efficacement ces points de code dans des octets ?
3.1 Limites de UTF-16
UTF-16 encode la plupart des caractères sur 2 octets, certains sur 4 (surrogates). Mais :
- Il casse la compatibilité avec ASCII.
- Il est moins efficace pour les langues occidentales (2 octets pour chaque lettre).
Il fallait un encodage plus souple et compatible avec l’existant.
4. Naissance d’UTF-8 (années 1990)
UTF-8 est conçu pour respecter trois contraintes majeures :
- Compatibilité totale avec ASCII : les 128 premiers caractères sont codés comme en ASCII.
- Encodage de tous les caractères Unicode : avec des séquences de 1 à 4 octets.
- Auto-synchronisation : chaque octet indique s’il est un début de caractère ou une continuation.
UTF-8 est standardisé dans les années 1990 et devient le standard d’Internet au début des années 2000.
5. Fonctionnement technique d’UTF-8
UTF-8 est un encodage à longueur variable :
- 1 octet pour les caractères ASCII.
- 2 octets pour beaucoup de caractères européens.
- 3 octets pour la plupart des écritures (grec, arabe, hébreu, etc.).
- 4 octets pour les emojis et caractères rares.
5.1 Forme des octets
1 octet : 0xxxxxxx
2 octets : 110xxxxx 10xxxxxx
3 octets : 1110xxxx 10xxxxxx 10xxxxxx
4 octets : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6. Exemples concrets
6.1 Lettre « é »
- Unicode : U+00E9
- UTF-8 : C3 A9 (en hexadécimal)
- Longueur : 2 octets
6.2 Symbole « € »
- Unicode : U+20AC
- UTF-8 : E2 82 AC
- Longueur : 3 octets
6.3 Emoji « 😄 »
- Unicode : U+1F604
- UTF-8 : F0 9F 98 84
- Longueur : 4 octets
7. Pourquoi UTF-8 a gagné ?
UTF-8 s’est imposé parce qu’il combine :
- Compatibilité ASCII : essentiel pour les anciens systèmes et Internet.
- Universalité Unicode : toutes les langues, tous les symboles.
- Efficacité : 1 octet pour les caractères les plus fréquents.
- Robustesse : auto-synchronisation, détection d’erreurs.
- Simplicité d’implémentation : facile à coder et à décoder.
Résultat : UTF-8 est aujourd’hui le codage dominant sur le Web et dans la plupart des systèmes modernes.
8. Conclusion
Le chemin vers UTF-8 suit une logique claire :
- ASCII : simple mais trop limité.
- ISO-8859 et autres tables : fragmentation et incompatibilités.
- Unicode : unification des caractères du monde entier.
- UTF-8 : encodage universel, efficace et compatible avec l’héritage ASCII.
C’est cette combinaison qui fait d’UTF-8 le standard de fait pour le texte numérique aujourd’hui.
Topo sur les octets de continuation en UTF-8
Définition
En UTF-8, un octet de continuation est un octet qui ne peut pas commencer une séquence de caractère. Il sert uniquement à compléter un caractère encodé sur plusieurs octets.
Forme binaire
Un octet de continuation a toujours la forme binaire :
10xxxxxx
Cela signifie que les deux bits de poids fort sont 10, et les six bits
restants (xxxxxx) contiennent une partie du code du caractère.
Rôle dans les séquences UTF-8
Les séquences UTF-8 se structurent ainsi :
- 1 octet :
0xxxxxxx(ASCII, aucun octet de continuation) - 2 octets :
110xxxxx+10xxxxxx - 3 octets :
1110xxxx+10xxxxxx+10xxxxxx - 4 octets :
11110xxx+10xxxxxx+10xxxxxx+10xxxxxx
Exemple : « é » (U+00E9)
UTF-8 : C3 A9
C3→11000011: octet de débutA9→10101001: octet de continuation
Exemple : emoji 😄 (U+1F604)
UTF-8 : F0 9F 98 84
F0→11110000: octet de début9F,98,84→10xxxxxx: trois octets de continuation
Décodage UTF-8
1. Principe général
UTF-8 encode chaque caractère sur 1 à 4 octets. Pour décoder une séquence UTF-8, il faut :
- Identifier le nombre d’octets grâce au premier octet.
- Retirer les préfixes inutiles (
0,110,1110,11110,10). - Assembler les bits utiles.
- Convertir le résultat en hexadécimal pour obtenir le point de code Unicode.
- Identifier le caractère correspondant.
2. Motifs des octets UTF-8
Le premier octet indique la longueur :
- 1 octet :
0xxxxxxx - 2 octets :
110xxxxx - 3 octets :
1110xxxx - 4 octets :
11110xxx
Les octets suivants sont toujours des octets de continuation :
10xxxxxx
3. Exemple complet : F0 9F 98 80 (emoji 😀)
Étape 1 : Déterminer la longueur
F0 en binaire → 11110000
Ce motif commence par 11110 → caractère encodé sur 4 octets.
Étape 2 : Convertir chaque octet en binaire et retirer les préfixes
F0→11110000→ préfixe11110→ bits utiles :0009F→10011111→ préfixe10→ bits utiles :01111198→10011000→ préfixe10→ bits utiles :01100080→10000000→ préfixe10→ bits utiles :000000
Étape 3 : Assembler les bits utiles
000 011111 011000 000000
Étape 4 : Convertir en hexadécimal
Le binaire complet devient : 0000111110110000000000
Converti en hexadécimal → 1F600
Étape 5 : Identifier le caractère
Le point de code Unicode U+1F600 correspond au caractère : 😀
4. Résumé
Décoder UTF-8 consiste à :
- Lire le premier octet pour connaître la longueur.
- Retirer les préfixes de chaque octet.
- Assembler les bits utiles.
- Convertir en hexadécimal.
- Obtenir le point de code Unicode et le caractère.
Encodage UTF-8 – Exemple au décodage
Objectif
À partir d’un point de code Unicode, reconstruire les octets UTF-8 correspondants.
Exemple : U+00E9 (le caractère « é »)
Étape 1 : Convertir le point de code en binaire
U+00E9 → en binaire : 0000 0000 1110 1001
Étape 2 : Déterminer la longueur UTF-8
Le point de code est supérieur à 0x007F → il nécessite 2 octets UTF-8.
- Format UTF-8 sur 2 octets :
110xxxxx 10xxxxxx
Étape 3 : Extraire les bits utiles
On prend les 11 bits significatifs du point de code :
11101001
On les découpe pour les insérer dans les deux octets UTF-8 :
- Premier octet : 5 bits →
11101 - Deuxième octet : 6 bits →
01001
Étape 4 : Insérer dans les masques UTF-8
-
Premier octet :
110xxxxx→11011101 -
Deuxième octet :
10xxxxxx→10101001
Étape 5 : Convertir en hexadécimal
11011101→ C310101001→ A9
Résultat final
Le caractère « é » (U+00E9) s’encode en UTF-8 sous la forme :
C3 A9
Résumé
- Convertir le point de code en binaire.
- Choisir le format UTF-8 (1 à 4 octets).
- Découper les bits utiles.
- Les insérer dans les masques UTF-8.
- Convertir en hexadécimal.