Textes et encodages — ASCII, ISO-8859-1, Unicode
Introduction
Vous savez désormais comment la machine code des nombres. Mais comment représente-t-elle un mot, une phrase, un emoji ? Aucun « A » ne vit dans la mémoire d'un ordinateur : seuls vivent des bits. Il faut donc une convention qui associe à chaque caractère un numéro, lui-même représentable en binaire. Cette convention s'appelle un encodage de caractères.
Plusieurs encodages ont coexisté dans l'histoire — chacun avec ses avantages et ses limites. Comprendre lequel est utilisé est essentiel pour ouvrir correctement un fichier texte, transmettre des données, ou simplement éviter qu'un accent ne se transforme en hiéroglyphe.
ASCII — l'ancêtre
L'ASCII (American Standard Code for Information Interchange) date de 1963. Il code chaque caractère sur 7 bits, soit valeurs possibles, de 0 à 127.
| Plage | Contenu |
|---|---|
| 0–31 | Caractères de contrôle (retour chariot, tabulation…) |
| 32–47 | Espace et ponctuation (!, ", #, etc.) |
| 48–57 | Chiffres 0–9 |
| 65–90 | Lettres majuscules A–Z |
| 97–122 | Lettres minuscules a–z |
Quelques codes à connaître :
| Caractère | Code décimal | Code binaire |
|---|---|---|
A | 65 | 1000001 |
a | 97 | 1100001 |
0 | 48 | 0110000 |
(espace) | 32 | 0100000 |
A vaut 65 et a vaut 97. C'est pour cela que basculer un
caractère en minuscule revient, en interne, à mettre un bit à 1.En Python, les fonctions ord() et chr() permettent de naviguer entre un
caractère et son code :
print(ord('A')) # 65
print(chr(97)) # 'a'
print(ord('0')) # 48
Limites évidentes de l'ASCII : pas d'accent, pas de é, à, ç. Le c
français cédille n'existe pas. L'ASCII est resté valable pour l'anglais, mais
intenable pour le reste du monde.
Quel est le code ASCII de la lettre Z ?
ISO-8859-1 — l'extension européenne
L'ISO-8859-1 (parfois appelée Latin-1) étend l'ASCII à 8 bits et
définit les 128 caractères supplémentaires (codes 128 à 255). On y trouve les
caractères accentués des langues d'Europe occidentale : é, à, ç, ñ,
ö…
| Caractère | Code décimal | Code hexa |
|---|---|---|
é | 233 | 0xE9 |
à | 224 | 0xE0 |
ç | 231 | 0xE7 |
ISO-8859-1 reste rétrocompatible avec l'ASCII : les 128 premiers codes sont identiques. Un fichier ASCII pur reste valide en ISO-8859-1.
Mais ISO-8859-1 ne couvre que l'Europe de l'Ouest. Pour le grec, le russe, l'arabe, le chinois… il a fallu d'autres variantes (ISO-8859-2, ISO-8859-5, etc.). Cette multiplication des encodages a vite tourné au cauchemar : un même octet ne signifiait plus la même chose selon le contexte.
Unicode — un caractère, un numéro universel
Unicode est né dans les années 1990 d'une ambition simple : attribuer un numéro unique à tous les caractères de toutes les langues du monde, plus les symboles, les emojis, les caractères mathématiques, etc.
Chaque caractère reçoit un code point (point de code), noté typiquement
U+XXXX où XXXX est sa valeur en hexadécimal :
| Caractère | Code point | Décimal |
|---|---|---|
A | U+0041 | 65 |
é | U+00E9 | 233 |
λ (lambda grec) | U+03BB | 955 |
日 (idéogramme japonais « jour ») | U+65E5 | 26 085 |
😀 | U+1F600 | 128 512 |
Unicode définit aujourd'hui plus de 150 000 caractères. Mais Unicode n'est qu'un catalogue : il dit quel numéro a chaque caractère, pas comment écrire ce numéro en mémoire. Pour cela, il faut un encodage, parmi plusieurs disponibles.
UTF-8 — l'encodage qui a tout emporté
UTF-8 est de loin l'encodage Unicode le plus utilisé aujourd'hui — sur le Web, dans les fichiers texte, dans la quasi-totalité des langages modernes.
Ses propriétés :
- Il code chaque caractère sur 1 à 4 octets selon sa valeur Unicode.
- Il est rétrocompatible avec l'ASCII : un fichier ASCII pur est aussi un fichier UTF-8 valide.
- Les caractères courants en anglais tiennent sur 1 octet, les caractères accentués courants sur 2 octets, les idéogrammes sur 3, certains emojis sur 4.
| Caractère | Code point | Octets en UTF-8 |
|---|---|---|
A | U+0041 | 41 (1 octet) |
é | U+00E9 | C3 A9 (2 octets) |
日 | U+65E5 | E6 97 A5 (3 octets) |
😀 | U+1F600 | F0 9F 98 80 (4 octets) |
Sortie attendue :
Chaîne : café
Octets : b'caf\xc3\xa9'
En hexa : 63 61 66 c3 a9
Longueur : 5 octets pour 4 caractères
b'...' signale à Python que l'objet est une suite d'octets
(bytes) — pas une chaîne de caractères. Les octets non imprimables comme
0xC3 sont affichés sous la forme \xc3 ; les octets correspondant à des
lettres ASCII sont affichés tels quels (c, a, f).Le é occupe 2 octets en UTF-8 alors qu'il n'occupe qu'un seul caractère
logique dans la chaîne Python.
Combien d'octets occupe la chaîne "é" en UTF-8 ?
Le bug classique des encodages mélangés
Imaginez un fichier notes.txt enregistré en UTF-8 par votre éditeur de texte.
Vous l'ouvrez ensuite avec un logiciel qui croit lire de l'ISO-8859-1. Que se
passe-t-il pour le mot café ?
- En UTF-8,
éest stocké comme les octets0xC3 0xA9. - Lus en ISO-8859-1, ces deux octets sont interprétés comme deux caractères
séparés :
Ã(code 195) et©(code 169).
Résultat à l'écran : café devient café. C'est le signe quasi universel
d'un fichier UTF-8 mal interprété.
é, à ou ç à la place d'accents,
c'est presque toujours un fichier UTF-8 lu comme ISO-8859-1. Le contenu n'est
pas corrompu — il est juste mal interprété.En Python — préciser l'encodage à l'ouverture
Python permet de préciser l'encodage à l'ouverture d'un fichier :
# Lecture explicite en UTF-8
with open("notes.txt", encoding="utf-8") as f:
contenu = f.read()
# Conversion en bytes puis dans un autre encodage
texte = "café"
octets_utf8 = texte.encode("utf-8") # b'caf\xc3\xa9'
octets_latin = texte.encode("latin-1") # b'caf\xe9'
Inversement, decode() reconstruit la chaîne à partir des octets, en précisant
l'encodage utilisé.
octets = b'caf\xc3\xa9'
print(octets.decode("utf-8")) # 'café' — correct
print(octets.decode("latin-1")) # 'café' — buggué
Pièges courants
- Toujours préciser l'encodage quand vous ouvrez un fichier texte
(
open("fichier.txt", encoding="utf-8")). Les valeurs par défaut varient d'un OS à l'autre. - Le nombre d'octets d'une chaîne (
len(s.encode())) n'est pas forcément le nombre de caractères (len(s)) — vrai uniquement en ASCII. - Un caractère emoji peut occuper jusqu'à 4 octets en UTF-8, et certains combinent plusieurs code points (famille, drapeaux…).
Pour aller plus loin
UTF-8 n'est pas le seul encodage Unicode. UTF-16 est utilisé en interne par Java, JavaScript et Windows ; UTF-32 (4 octets par caractère, fixe) est rare mais simple. Le Web s'est concentré sur UTF-8 pour sa compacité et sa rétrocompatibilité ASCII — c'est aujourd'hui le standard de facto.