21 - Représentation des textes
Exercice 1 : QCM – vérification des prérequis
Pour chaque question, une seule réponse est correcte.
1. En ASCII, combien de caractères différents peut-on coder ?
- A. 26 (les lettres de l’alphabet)
- B. 128
- C. 256
- D. Plus d’un million
Correction
Réponse : B. L’ASCII utilise sept bits, ce qui permet de coder $2^7 = 128$ caractères (dont les lettres majuscules, minuscules, chiffres, ponctuation et caractères de contrôle).
- A est faux : 26 est le nombre de lettres de l’alphabet, mais l’ASCII code aussi les chiffres, la ponctuation, les majuscules, etc.
- C est faux : 256 correspond à huit bits (ASCII étendu ou ISO 8859), pas à l’ASCII standard.
- D est faux : c’est l’ordre de grandeur d’Unicode, pas d’ASCII.
2. En ASCII, le code de 'A' est 65 et celui de 'a' est 97. Quel est le code de 'C' ?
- A. 66
- B. 67
- C. 99
- D. 68
Correction
Réponse : B. Les lettres majuscules sont codées consécutivement : A = 65, B = 66, C = 67.
- A est faux : 66 correspond à
'B', pas à'C'. Erreur de décalage d’une unité. - C est faux : 99 correspond à
'c'(minuscule). Confusion majuscule/minuscule. - D est faux : 68 correspond à
'D'.
3. Pourquoi a-t-on créé Unicode ?
- A. Pour remplacer le binaire par l’hexadécimal
- B. Pour pouvoir représenter les caractères de toutes les langues du monde
- C. Pour compresser les fichiers texte
- D. Pour accélérer l’affichage des pages Web
Correction
Réponse : B. L’ASCII ne code que 128 caractères (alphabet latin sans accents). Pour représenter le chinois, l’arabe, le cyrillique, les emojis, etc., il fallait un standard universel : c’est Unicode (plus de 150 000 caractères).
- A est faux : Unicode n’a rien à voir avec le système de numération.
- C est faux : Unicode ne compresse pas ; c’est un standard d’encodage.
- D est faux : Unicode ne concerne pas la vitesse d’affichage.
4. En UTF-8, un caractère ASCII standard (comme 'A') est codé sur :
- A. 1 octet
- B. 2 octets
- C. 3 octets
- D. 4 octets
Correction
Réponse : A. UTF-8 est un encodage à longueur variable. Les 128 caractères ASCII sont codés sur un seul octet (compatibilité avec l’ASCII). Les caractères accentués (é, è, ê) utilisent deux octets. Les caractères asiatiques ou les emojis en utilisent trois ou quatre.
- B, C et D sont faux : ces tailles sont utilisées pour d’autres caractères Unicode, pas pour les caractères ASCII de base.
Exercice 2 : exemple travaillé – encoder un mot en ASCII
Objectif : encoder le mot NSI en ASCII (décimal, hexadécimal et binaire).
Étape 1. Trouver le code ASCII décimal de chaque caractère (à l’aide de la table ou de Python avec ord()) :
'N'→ 78'S'→ 83'I'→ 73
Étape 2. Convertir en hexadécimal :
- $78 = 4 \times 16 + 14$, soit $\text{4E}_{16}$
- $83 = 5 \times 16 + 3$, soit $\text{53}_{16}$
- $73 = 4 \times 16 + 9$, soit $\text{49}_{16}$
Étape 3. Convertir en binaire (sur huit bits) :
- $78 = 01001110_2$
- $83 = 01010011_2$
- $73 = 01001001_2$
Résultat : le mot « NSI » s’encode en 01001110 01010011 01001001.
Vérification avec Python :
for c in "NSI":
print(f"'{c}' → décimal: {ord(c)}, hex: {hex(ord(c))}, bin: {bin(ord(c))}")
Exercice 3 : encodage guidé
3.1 Encoder en ASCII
Compléter le tableau pour le mot Bye :
| Caractère | Code décimal | Code hexadécimal | Code binaire (8 bits) |
|---|---|---|---|
'B' | … | … | … |
'y' | … | … | … |
'e' | … | … | … |
Indication : 'A' = 65, 'a' = 97, les lettres se suivent dans l’ordre alphabétique.
Correction
| Caractère | Code décimal | Code hexadécimal | Code binaire (8 bits) |
|---|---|---|---|
'B' | 66 ($= 65 + 1$) | $\text{42}_{16}$ | $01000010_2$ |
'y' | 121 ($= 97 + 24$) | $\text{79}_{16}$ | $01111001_2$ |
'e' | 101 ($= 97 + 4$) | $\text{65}_{16}$ | $01100101_2$ |
3.2 Décoder un message ASCII
Décoder le message suivant (codes ASCII décimaux) : 72 101 108 108 111.
Indication : procéder caractère par caractère en utilisant la table ASCII.
Correction
- 72 →
'H'($= 65 + 7$) - 101 →
'e'($= 97 + 4$) - 108 →
'l'($= 97 + 11$) - 108 →
'l' - 111 →
'o'($= 97 + 14$)
Le message est Hello.
Exercice 4 : encodage et décodage autonomes
Encoder en ASCII binaire (huit bits par caractère) la phrase :
Le but.Décoder le message ASCII binaire suivant :
01000010 01110010 01100001 01110110 01101111En Python, écrire une fonction
encoder(texte)qui prend une chaîne et renvoie la liste des codes ASCII (entiers).
Correction
1. Phrase « Le but » :
'L'= 76 = $01001100_2$'e'= 101 = $01100101_2$' '= 32 = $00100000_2$'b'= 98 = $01100010_2$'u'= 117 = $01110101_2$'t'= 116 = $01110100_2$
Suite binaire : 01001100 01100101 00100000 01100010 01110101 01110100
2. Décodage :
- $01000010_2 = 66$ →
'B' - $01110010_2 = 114$ →
'r' - $01100001_2 = 97$ →
'a' - $01110110_2 = 118$ →
'v' - $01101111_2 = 111$ →
'o'
Le message est Bravo.
3. Fonction Python :
def encoder(texte):
return [ord(c) for c in texte]
print(encoder("NSI")) # [78, 83, 73]
Exercice 5 : ASCII et propriétés numériques
- En ASCII, quel est l’écart entre le code d’une lettre majuscule et le code de la même lettre minuscule ? (Tester avec quelques lettres.)
- En déduire une fonction Python
majuscule(c)qui transforme une lettre minuscule en majuscule sans utiliser la méthode.upper(). - En ASCII, le caractère
'0'a le code 48. Écrire une fonctionchiffre_vers_entier(c)qui convertit un caractère chiffre ('0'à'9') en l’entier correspondant, sans utiliserint().
Correction
1. L’écart est toujours 32 : 'a' − 'A' = 97 − 65 = 32, 'b' − 'B' = 98 − 66 = 32, etc. En binaire, cela correspond au bit 5 (position $2^5 = 32$).
2.
def majuscule(c):
return chr(ord(c) - 32)
print(majuscule('n')) # 'N'
print(majuscule('s')) # 'S'
3.
def chiffre_vers_entier(c):
return ord(c) - ord('0')
print(chiffre_vers_entier('7')) # 7
print(chiffre_vers_entier('0')) # 0
Propriété utilisée : les chiffres '0' à '9' ont des codes consécutifs (48 à 57), tout comme les lettres majuscules (65 à 90) et minuscules (97 à 122). C’est un choix de conception de l’ASCII.
Exercice 6 : UTF-8 et caractères accentués
- En Python, comparer
len('café')etlen('café'.encode('utf-8')). Expliquer la différence. - Le caractère
'é'a le point de code Unicode U+00E9 ($= 233_{10}$). Combien d’octets UTF-8 sont nécessaires pour le coder ? (Rappel : 0 à 127 → un octet ; 128 à 2047 → deux octets.) - L’emoji 🎓 a le point de code U+1F393. Combien d’octets UTF-8 sont nécessaires ?
Correction
1. len('café') renvoie 4 (quatre caractères). len('café'.encode('utf-8')) renvoie 5 (cinq octets), car 'é' est codé sur deux octets en UTF-8, tandis que les trois autres caractères (c, a, f) sont codés sur un seul octet chacun.
2. Le point de code 233 est dans l’intervalle 128–2047, donc 'é' est codé sur deux octets en UTF-8.
3. Le point de code $\text{1F393}{16} = 127,891{10}$ est supérieur à 65 535, donc l’emoji 🎓 est codé sur quatre octets en UTF-8.
Règle UTF-8 :
- 0–127 : un octet (compatible ASCII)
- 128–2047 : deux octets (lettres accentuées, cyrillique, etc.)
- 2048–65 535 : trois octets (chinois, japonais, etc.)
- 65 536 et au-delà : quatre octets (emojis, symboles rares)
Exercice 7 : synthèse – message secret multilangue
Un site Web affiche des caractères incorrects (des é au lieu de é). Ce problème s’appelle un mojibake.
- Expliquer pourquoi ce problème se produit (indice : le fichier est encodé dans un format mais lu dans un autre).
- En Python, simuler le problème : encoder la chaîne
'été'en UTF-8, puis la décoder en Latin-1 ('iso-8859-1'). Qu’obtient-on ? - Comment corriger ce problème sur un site Web ? Quelle balise HTML faut-il vérifier ?
Correction
1. Le mojibake se produit quand un fichier encodé en UTF-8 est interprété avec un autre encodage (par exemple Latin-1 ou Windows-1252). Chaque octet UTF-8 est alors interprété comme un caractère Latin-1 différent, ce qui produit des symboles incohérents.
2.
texte = 'été'
octets = texte.encode('utf-8') # b'\xc3\xa9t\xc3\xa9'
print(octets.decode('iso-8859-1')) # été
Le 'é' (deux octets UTF-8 : C3 A9) est interprété comme deux caractères Latin-1 : Ã (C3) et © (A9).
3. Il faut s’assurer que la balise <meta charset="utf-8"> est présente dans la section <head> du fichier HTML. Cette balise indique au navigateur quel encodage utiliser pour interpréter le fichier.