30 - Encodage des textes
Prérequis : Cette activité s'effectue normalement après avoir effectué celle de la partie Donnée sur l'intérêt de l'hexadécimal. Vous devez donc normalement comprendre le principe de l'ASCII et savoir exprimer un nombre en base 10 (décimal) ou en base 16 (hexadécimal).
Après cette activité, vous comprendrez les blagues de ce style :
Logiciel nécessaire pour l'activité : Python 3 : Thonny, IDLE ...
Evaluation ✎ : questions 04-05-06-09-10-11-13-14-18-19-20
Documents de cours : open document ou pdf
1 - ASCII
Nous avons vu que les ordinateurs stockent uniquement des bits associés en octets :
- un nombre entier est représenté par un ou plusieurs octets
- un nombre à virgule est représenté par une suite d'octets
- une image est représentée par une suite d'octets,
- un texte est représenté par une suite d'octets.
On a donc besoin d'une table de conversion lorsqu'on veut écrire un texte ou qu'on veut le lire . Sans la technique de conversion, impossible de savoir les nombres qu'il faut écrire à la place du texte initial ou comment décoder les nombres qu'on est en train de lire !
La transformation caractère en nombre est ce qu'on nomme l'encodage quelque soit la base utilisée pour exprimer le nombre associé.
A ➔ 100 0001
2
A ➔ 65 10
A ➔ 41 16
La transformation nombre vers caractère est ce qu'on nomme le décodage.
100 0001
2 ➔ A
65 10 ➔ A
41 16 ➔ A
Initialement, la mémoire des ordinateurs n'était pas très grande et les communications n'étaient pas très fiables.
Principe de la table ASCII
La première table normalisée partagée à grande échelle est la table ASCII pour American Standard Code for Information Interchange.
La table ASCII est devenue le standard incontournable des 128 premiers caractères.
Elle est publiée pour la première fois en 1963 et est le résultat d'un groupe de travail.
La table ASCII attribue des valeurs codifiées
- à 32 caractères dits caractères de contrôle : passage à la ligne, début de fichier, fin de fichier...
- aux lettres minuscules (a-z)
- aux lettres majuscules (A-F)
- aux chiffres décimaux (0-9)
- aux caractères de ponctuation :
.
,
;
... - à quelques symboles :
+
-
*
/
...
Avant cela, chaque matériel avait sa propre table d'encodage/décodage... Changer de support impliquait donc de changer les codes à inscrire !
Taille de l'encodage
La taille choisie pour l'encodage des caractères était de 7 bits. On pouvait donc encoder 27, soit 128 caractères au total. Pas un de plus. Cela représentait une place mémoire non négligeable à l'époque : on était à quelques centaines de kilo-octets (ko) à l'époque. De quoi encoder un petit livre uniquement.
Exemple : un petit bout de la table ASCII
Caractère encodé | En binaire (7 bits) | En décimal | En hexadécimal |
---|---|---|---|
A | 100 0001 |
65 | 41 |
B | 100 0010 |
66 | 42 |
C | 100 0011 |
67 | 43 |
Sous cette forme de tableau avec une ligne par caractère, cela va donner 128 lignes. Cette représentation prendrait beaucoup de place.
On préfère représenter la correspondance Code/Caractère via un tableau à deux entrées.
Quelques alias du nom ASCII :
- iso-ir-6
- ANSI_X3.4-1968
- ANSI_X3.4-1986
- ISO_646.irv:1991
- ISO646-US
- US-ASCII
- us
- IBM367
- cp367
- csASCII
Les premières questions vous permettront de remettre vos connaissances sur les bases 2 et 16 à jour.
01° Montrer que
- 41 16 correspond bien à 65 10.
- 0A 16 correspond bien à 10 10.
- 20 16 correspond bien à 32 10.
Montrer ensuite que 100 0001
2< correspond bien à 65 10.
...CORRECTION...
Calculons la valeur du nombre en base 10.
41
16
= (4 * 16 + 1)
10
= (64 + 1)
10
= 65
10
On peut faire la même chose avec le binaire.
100 0001
2
= (1 * 64 + 1 * 1)
10
= 65
10
02° En décomposant 0100 0001
en deux quartets, montrer que ce nombre s'écrit bien 41 16.
En utilisant la méthode des quartets, retrouver l'écriture binaire de 0A 16 et 20 16.
...CORRECTION...
100 0001
peut s'écrire 0100
et 0001
On voit immédiatement que le premier quartet correspond à 4 et le deuxième à 1.
Bit de parité
Les communications n'étant pas très fiables à l'époque, le 8e bit servait de bit de contrôle lors des communications : un exemple possible à l'émission,
- si le code du caractère comporte un nombre pair de bits à 1, on met le 8e à 0 : on a au total un nombre pair de bits à 1,
- si le code du caractère comporte un nombre impair de bits à 1, on met le 8e à 1 : on a au total un nombre pair de bits à 1,
Voici ce qu'on devrait envoyer pour émettre un A, un B ou un C.
Caractère encodé | En binaire (7 bits) | Nombre de bits à 1 |
---|---|---|
A | 0100 0001 |
2 donc pair |
B | 0100 0010 |
2 donc pair |
C | 1100 0011 |
4 donc pair |
L'ordinateur récepteur pouvait alors faire la même chose sur les 7 bits. En comparant à la valeur du 8e bit, on pouvait savoir si une erreur de transmission avait à priori eu lieu.
Exemples de réception
Je reçois 0111 0010
: il y a un nombre pair de 1, j'accepte cette valeur.
Je reçois 1111 0010
: il y a un nombre impair de 1, je refuse cette valeur.
03° Expliquer si les codes de caractères ci-dessous, reçus par un ordinateur sont possiblement erronés.
1100 0111
1100 1111
...CORRECTION...
Le premier est invalide : il y 5 bits à 1. Une erreur de transmission est détéctée.
Le deuxième comporte 6 bits à 1. Un nombre pair. Soit la communication est bonne, soit il y a eu plusieurs erreurs en même temps !
Table ASCII (en version hexadécimale)
Voici la table ASCII complète, en version hexadécimale. Vous pouvez visualiser la valeur décimale d'un caractère en stabilisant la souris au dessus du caractère.
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0_ | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI | _0 |
1_ | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US | 1_ |
2_ | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | 2_ | |
3_ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | 3_ |
4_ | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | 4_ |
5_ | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | 5_ |
6_ | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | 6_ |
7_ | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DEL | 7_ |
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
✎ 04° Utiliser le tableau pour trouver le nom du caractère qui correspond à la valeur 0A 16 : le nom apparaît au survol de la case.
Avec quelle association de caractères d'échappement parvient-on à le symboliser en Python ?
\t
?\n
?\f
?
2 - Encodage avec Python
Voyons maintenant comment Python parvient à gérer ces histoires d'encodage.
Méthode des strings permettant d'encoder : encode
On peut créer une suite d'octets en Python en utilisant la méthode encode. Cette méthode attend au moins un string contenant le nom de l'encodage à utiliser en argument.
La méthode renvoie un objet de type bytes qui veut dire usuellement octets.
>>> octets = "ABCDE".encode('ascii')
>>> type(octets)
<class 'bytes'>
Voyons comment récuper les valeurs (0 à 255 en décimal) de deux façons différentes.
Méthode 1 - Utilisation d'une boucle FOR
Remarque : il faut appuyer deux fois sur ENTREE pour lancer la boucle FOR depuis la console.
Lecture directe de la valeur
>>> for octet in octets : print(octet)
65
66
67
68
69
Lecture par utilisation de l'indice
>>> for i in range(len(octets)) : print(octets[i])
65
66
67
68
69
Méthode 2 - Utilisation de la fonction list
>>> tableau = list(octets)
>>> tableau
[65, 66, 67, 68, 69]
Affichage des bytes par Python
Python affiche les bytes comme des strings précédés d'un b minuscule.
>>> print(octets)
b'ABCDE'
Si la valeur de l'octet correspond à un caractère ASCII imprimable, l'interpréteur va alors afficher le caractère plutôt que la valeur.
✎ 05° Utiliser les instructions ci-dessous dans votre Console. Répondre ensuite aux questions :
>>> texte = "AB\nCD"
>>> print(texte)
AB
CD
>>> octets = texte.encode('ascii')
>>> octets
b'AB\nCD'
>>> len(octets)
5
>>> list(octets)
[65, 66, 10, 67, 68]
Questions :
- Que représente
\n
? - Par quel octet est-il encodé ?
- Pourquoi le string
'AB\nCD'
est-il encodé par 5 octets alors qu'on voit clairement 6 caractères ?
✎ 06° Utiliser Python (ou à la main, mais ça va être long) pour trouver la façon dont on encode la chaîne de caractères suivante qui ne comporte aucun accent :"Bonjour a tous, l'ASCII permet d'encoder beaucoup de caracteres mais pas tous : il s'agit d'un encodage cree par les americains et donc beaucoup de caracteres des langages europeens ou asiatiques ne sont absolument pas presents dans cette table. C'est pour cela que je vous demande de ne pas mettre d'accents dans les noms de variables en Python, meme si nous verrons que le langage Python sait les gerer. Mais ce n'est pas le cas de tous les langages de programmation."
Question supplémentaire : combien d'octets sont nécessaires en mémoire pour stocker ce texte en ASCII ? Pensez à utiliser la fonction native len : elle fonctionne aussi sur les objets bytes.
Question : peut-on tout écrire avec l'ASCII ?
Essayons maintenant de faire la même chose mais avec un texte réel : un texte avec des caractères étranges pour un lecteur américain.
>>> a = "Bonjour à tous, l'ASCII permet d'encoder beaucoup de caractères mais pas tous : il s'agit d'un encodage créé par les américains et donc beaucoup de caractères des langages européens ou asiatiques ne sont absolument pas présents dans cette table. C'est pour cela que je vous demande de ne pas mettre d'accents dans les noms de variables en Python, même si nous verrons que le langage Python sait les gérer. Mais ce n'est pas le cas de tous les langages de programmation."
Aucun problème pour créer le string : Python sait très bien gérer les accents dans les chaînes de caractères.
Passons à la suite : la création des octets-bytes encodant en ASCII ce texte de façon à pouvoir l'enregistrer dans un fichier-texte :
>>> b = a.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\xe0' in position 8: ordinal not in range(128)
Et voilà : un beau message d'erreur. Visiblement le caractère d'index 8 pose problème.
>>> a[8]
'à'
Pourquoi ce caractère pose-t-il problème ?: simplement car il n'est pas dans la table ASCII. On aura donc du mal à trouver la valeur de l'octet à lui faire correspondre !
Avec la rapide augmentation des mémoires, l'encodage des caractères est passé de 7 bits à 8 bits.
Un bit en plus veut alors dire qu'on double le nombre de caractères disponibles : on est passé
- de 27 (128, de 0 à 127) valeurs disponibles
- à 28 (256, de 0 à 255) valeurs disponibles.
Soit 128 nouvelles valeurs permettant d'encoder 128 nouveaux glyphes.
Une révolution : deux fois plus de caractères !
3 - Les tables ASCII étendues (sur un octet)
Les tables cp sont les tables d'encodage "code page" créés par IBM sur les premiers ordinateurs personnels.
Pendant très lontemps, l'une des plus connue a été la page de code 437 cp-437 utilisé par IBM pour le système DOS et ces consoles.
La première partie de ces tables n'est pas reproduite car ce sont les mêmes codes que l'ASCII : le but est d'être compatible avec les caractères 0-127 d'ASCII.
On ne représente donc ici que les 128 caractères rajoutés dont les valeurs sont entre 128 (en hexa 8016) et 255 (en hexa FF16).
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x8_ | Ç | ü | é | â | ä | à | å | ç | ê | ë | è | ï | î | ì | Ä | Å | 0x8_ |
0x9_ | É | æ | Æ | ô | ö | ò | û | ù | ÿ | Ö | Ü | ¢ | £ | ¥ | ₧ | ƒ | 0x9_ |
0xA_ | á | í | ó | ú | ñ | Ñ | ª | º | ¿ | ⌐ | ¬ | ½ | ¼ | ¡ | « | » | 0xA_ |
0xB_ | ░ | ▒ | ▓ | │ | ┤ | ╡ | ╢ | ╖ | ╕ | ╣ | ║ | ╗ | ╝ | ╜ | ╛ | ┐ | 0xB_ |
0xC_ | └ | ┴ | ┬ | ├ | ─ | ┼ | ╞ | ╟ | ╚ | ╔ | ╩ | ╦ | ╠ | ═ | ╬ | ╧ | 0xC_ |
0xD_ | ╨ | ╤ | ╥ | ╙ | ╘ | ╒ | ╓ | ╫ | ╪ | ┘ | ┌ | █ | ▄ | ▌ | ▐ | ▀ | 0xD_ |
0xE_ | α | ß | Γ | π | Σ | σ | µ | τ | Φ | Θ | Ω | δ | ∞ | φ | ε | ∩ | 0xE_ |
0xF_ | ≡ | ± | ≥ | ≤ | ⌠ | ⌡ | ÷ | ≈ | ° | ∙ | · | √ | ⁿ | ² | ■ | ¤¤¤ | 0xF_ |
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
Vous pourriez vous demander pourquoi ils ont placé autant de caractères graphiques ? Simplement car à l'époque les affichages étaient encore très basiques. Pas d'environnement graphique. Ces caractères permettaient de réaliser de jolis tableaux.
Ces tables ont permis de donner encore plus de créativité aux gens qui réalisaient (et réalisent encore) une forme d'art : l'ASCII-Art.
_________________________________________________
| _ _ ____ ____ ___ ___ |
| __ _ _ __| |_ / \ / ___| / ___|_ _|_ _| |
| / _` | '__| __| / _ \ \___ \| | | | | | |
| | (_| | | | |_ / ___ \ ___) | |___ | | | | |
| \__,_|_| \__|/_/ \_\____/ \____|___|___| |
|_______________________________________________|
))
\||/ ((
| @@___oo))
/\ /\ / (__,,,,|
) /^\) ^\/ _)
) /^\/ _)
) _ / / _)
/\ )/\/ || | )_)
< > |(,,) )__)
|| / \)___)\
| \____( )___) )___
\______(_______;;; __;;;
\|/(_)_(_)\|/
@~ (o.o) ~@
/___( * )___\ NA NA
/ `U' \ NANA
( . ) NA !!!
`>---<'
_\ /_
o
_====| o
====|_====|
_====| | ====| I-I-I-I-I _ _ _ _ _ _
_ _ _ _ _ _ ====| | | \ ` ' / I-I-I-I-I-I
I-I-I-I-I-I | | | |. | \ ` '_/
\ ` '_/ | / \ | | /^\| |__ [],|
[*] __| ^ / ^ \ ^ | [*]| _|______|_
|__ ,| / \ / `\ / \ | ===| <=-=-==-=-=>
___| ___ |__ / /=_=_=_=\ \ |, _| \__ _'_/
I_I__I_I__I_I (====(_________)___) |____| ___ |. _ |
\-\--|-|--/-/ | | [*I__| I_I__I____I_I_I | _ |
|[] '| | | __ . | \-\--|-|--/-/ |` '|
|. ' | __| ___ |__ ___ |__ |---------| | [] |
/ \ [] .|_| |_| |_| |_| |_| |_| [] [] | | ` |
(===) .|-=-=-=-=-=-=-=-=-=-=-| / \ |[] |
| []|` [] | . . . . . . . . . |- (===) |` __|
| []| ` |/////////\\\\\\\\\\ |__. |[] | /| |
<===> ' ||||| |||| | [] <===>-I-I-I-I-I-I-I-I-| ` I-|
\I/ 1-- ||||| Maze's |||| | . ' \i/ . | | _|
| . _||||| FunHouse |||| | | ----' |` .|
../|',v,.,,,.|||||/_________\||||,/|.,,.Y,,..|\__
Pour pouvoir afficher correctement ces dessins sur d'autres supports, il faut impérativement utiliser des polices de caractères à chasse fixe, c'est à dire que chaque caractère doit avoir exactement la même largeur.
Sinon, l'image est déformée.
Les logiciels permettant d'éditer du code sont habituellement à chasse fixe.
07° Pour voir les encodages disponibles sur votre machine, vous pouvez lancer le code suivant.
1
2
3
4
5
6
7
8
9
10
11
12 | import encodings
def lister_les_encodages():
"""Fonction qui renvoie un tableau contenant les encodages disponibles"""
les_encodages = [e for e in sorted(set(encodings.aliases.aliases.values()))]
return les_encodages
if __name__ == '__main__':
print('Liste des encodages disponibles')
for element in lister_les_encodages():
print(f'- {element}')
|
Ce code utilise set, un ensemble. C'est une structure différente de list. Notamment, un ensemble est conçu pour ne pas contenir plusieurs fois des éléments identiques. Vous pouvez lancer le code en remplaçant set par list : vous allez voir qu'on obtient alors plusieurs fois les mêmes noms.
Vous devriez en trouver un beau paquet. Nous allons voir pourquoi il y en a autant...
A titre d'exemple, voici la liste obtenue avec sur mon système (en blanc : ceux dont nous allons parler aujourd'hui) :
Liste des encodages disponibles
- ascii
- base64_codec
- big5
- big5hkscs
- bz2_codec
- cp037
- cp1026
- cp1125
- cp1140
- cp1250
- cp1251
- cp1252
- cp1253
- cp1254
- cp1255
- cp1256
- cp1257
- cp1258
- cp273
- cp424
- cp437
- cp500
- cp775
- cp850
- cp852
- cp855
- cp857
- cp858
- cp860
- cp861
- cp862
- cp863
- cp864
- cp865
- cp866
- cp869
- cp932
- cp949
- cp950
- euc_jis_2004
- euc_jisx0213
- euc_jp
- euc_kr
- gb18030
- gb2312
- gbk
- hex_codec
- hp_roman8
- hz
- iso2022_jp
- iso2022_jp_1
- iso2022_jp_2
- iso2022_jp_2004
- iso2022_jp_3
- iso2022_jp_ext
- iso2022_kr
- iso8859_10
- iso8859_11
- iso8859_13
- iso8859_14
- iso8859_15
- iso8859_16
- iso8859_2
- iso8859_3
- iso8859_4
- iso8859_5
- iso8859_6
- iso8859_7
- iso8859_8
- iso8859_9
- johab
- koi8_r
- kz1048
- latin_1
- mac_cyrillic
- mac_greek
- mac_iceland
- mac_latin2
- mac_roman
- mac_turkish
- mbcs
- ptcp154
- quopri_codec
- rot_13
- shift_jis
- shift_jis_2004
- shift_jisx0213
- tactis
- tis_620
- utf_16
- utf_16_be
- utf_16_le
- utf_32
- utf_32_be
- utf_32_le
- utf_7
- utf_8
- uu_codec
- zlib_codec
08° Lancer maintenant le code suivant qui vous donnera la façon d'encoder les caractères accentués en utilisant la table cp437.
1
2
3
4
5
6
7
8
9
10
11
12
13 | texte = "Test avec é, des à et des è"
octets = texte.encode('cp437')
print('\nLe string de base')
print(texte)
print("\nLa suite d'octets")
print(octets)
print("\nLa suite d'octets sous forme de liste")
for octet in octets:
print(octet, end=' ')
|
La présence de \x
veut dire qu'il s'agit d'un code hexadécimal d'un caractère non-ASCII : les valeurs sont supérieures ou égales à 128 en base 10 ou 80 en base 16.
Questions
- En comparant les trois affichages, trouver l'encodage en hexadécimal et décimal des é avec cp437.
- Idem pour le à
- Idem pour le è
...CORRECTION...
Si votre code ne parvient pas à se lancer pour une raison ou une autre, voici le résultat de l'affichage :
Le string de base
Test avec é, des à et des è
La suite d'octets
b'Test avec \x82, des \x85 et des \x8a'
La suite d'octets sous forme de liste
84 101 115 116 32 97 118 101 99 32 130 44 32 100
101 115 32 133 32 101 116 32 100 101 115 32 138
Voici la première ligne de la table cp437 avec les caractères voulus en rouge : on voit bien qu'avec cette table é est encodé par 8216 que Python écrit 0x82.
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x8_ | Ç | ü | é | â | ä | à | å | ç | ê | ë | è | ï | î | ì | Ä | Å | 0x8_ |
La façon étrange d'afficher les objets bytes a une raison d'être : on voit rapidement les caractères qui ne sont pas des caractères ASCII (les caractères de 0 à 127).
La suite d'octets
b'Test avec \x82, des \x85 et des \x8a'
Si on résume dans une table :
Caractère encodé | En binaire (8 bits) | En décimal | En hexadécimal |
---|---|---|---|
é | 1000 0010 |
130 | 82 |
à | 1000 0101 |
133 | 85 |
é | 1000 1010 |
138 | 8a |
Pendant longtemps, il y a donc eu une multitude de tables :
- des tables pour ceux qui voulaient plutôt des caractères graphiques,
- des tables pour les pays d'Europe de l'Ouest,
- des tables pour les pays d'Europe du Nord,
- des tables pour le cyrillique,
- des tables pour les caractères asiatiques spécifiques,
- et même des tables par constructeurs
- ou par systèmes d'exploitation !
Bref, il n'était pas toujours facile de parvenir à décoder correctement un texte si on ne connaissait pas l'encodage qui avait été utilisé.
Table latin-1 ou iso8859_1
L'une des autres tables très utilisée en Europe est la table iso8859_1, de son petit nom latin-1.
Elle comporte tous les caractères usuels pour écrire un texte dans l'une des langues de l'Europe de l'Ouest et reste entièrement compatible avec l'ASCII sur les caractères de valeurs inférieures à 128.
Je ne fournis ici que la moitié supérieure de la table, la partie inférieure (0-127) est entièrement composée des caractères ASCII.
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x8_ | PAD | HOP | BPH | NBH | IND | NEL | SSA | ESA | HTS | HTJ | LTS | PLD | PLU | RI | SS2 | SS3 | 0x8_ |
0x9_ | DCS | PU1 | PU2 | STS | CCH | MW | SPA | EPA | SOS | SGCI | SCI | CSI | ST | OSC | PM | APC | 0x9_ |
0xA_ | NBSP | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | SHY | ® | ¯ | 0xA_ |
0xB_ | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ | 0xB_ |
0xC_ | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï | 0xC_ |
0xD_ | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß | 0xD_ |
0xE_ | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï | 0xE_ |
0xF_ | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ | 0xF_ |
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
Remarquez bien qu'elle n'inclut pas de caractères graphiques : les applications graphiques sont apparues. Plus besoin de réaliser de tableaux ou de dessins sur la console en utilisant des caractères, on utilisait déjà à cette époque de vraies images par exemple.
Voici les alias courants de cette table :
- ISO_8859-1:1987
- ISO_8859-1
- ISO-8859-1
- iso-ir-100
- csISOLatin1
- latin1
- l1
- IBM819
- CP819
✎ 09° Trois questions.
- 1 - En vous inspirant des codes précédents, fournir les octets permettant d'encoder ce texte en latin-1 puis en cp437.
- 2 - Quel est le seul caractère dont l'encodage est différent sur les deux tables ici ?
- 3 - Peut-on décoder à coup sur des octets (bytes) si on ne connait pas la table qui a servi à les créer ?
Le texte : "Perceval ne sait vraiment pas écrire en latin !"
.
Je n'ai présenté ici qu'une toute petite partie des tables d'encodage qui étaient (et sont encore) disponibles. Plus d'exemple dans la fiche présentée en fin d'activité.
Sachez néanmoins que la table latin-1 a connu une mise à jour importante pour l'Europe : la table latin-9 (également nommée iso8859_15) inclut en effet un caractère qui n'existait pas au moment de la création de la première : le signe de l'Euro, la monnaie.
Latin-9, une sorte de mise à jour de latin-1
En rose, les quelques associations valeurs-caractères qui ont changé par rapport à latin-1.
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x8_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | 0x8_ |
0x9_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | 0x9_ |
0xA_ | ¤¤¤ | ¡ | ¢ | £ | € | ¥ | Š | § | š | © | ª | « | ¬ | ¤¤¤ | ® | ¯ | 0xA_ |
0xB_ | ° | ± | ² | ³ | Ž | µ | ¶ | · | ž | ¹ | º | » | Œ | œ | Ÿ | ¿ | 0xB_ |
0xC_ | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï | 0xC_ |
0xD_ | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß | 0xD_ |
0xE_ | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï | 0xE_ |
0xF_ | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ | 0xF_ |
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
Un dernier exemple pour la route, l'iso-8859-11 ou Thai. Les 128 premières valeurs sont celles de l'ASCII, c'est à partir de 128 que ça diffère. Il y a même 8 valeurs non utilisées.
...iso-8859-11...
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x8_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | 0x8_ |
0x9_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | 0x9_ |
0xA_ | ¤¤¤ | ก | ข | ฃ | ค | ฅ | ฆ | ง | จ | ฉ | ช | ซ | ฌ | ญ | ฎ | ฏ | 0xA_ |
0xB_ | ฐ | ฑ | ฒ | ณ | ด | ต | ถ | ท | ธ | น | บ | ป | ผ | ฝ | พ | ฟ | 0xB_ |
0xC_ | ภ | ม | ย | ร | ฤ | ล | ฦ | ว | ศ | ษ | ส | ห | ฬ | อ | ฮ | ฯ | 0xC_ |
0xD_ | ะ | ั | า | ำ | ิ | ี | ึ | ื | ุ | ู | ฺ | � | � | � | � | ฿ | 0xD_ |
0xE_ | เ | แ | โ | ใ | ไ | ๅ | ๆ | ็ | ่ | ้ | ๊ | ๋ | ์ | ํ | ๎ | ๏ | 0xE_ |
0xF_ | ๐ | ๑ | ๒ | ๓ | ๔ | ๕ | ๖ | ๗ | ๘ | ๙ | ๚ | ๛ | � | � | � | � | 0xF_ |
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
Tables d'encodage sur un octet
Il existe une multitude de tables d'encodages sur un octet permettant d'écrire dans toutes les langues.
Pourquoi "encodage sur un octet" ? Tout simplement car toutes ces tables contiennent 256 associations valeurs-caractères qui permettent d'encoder un texte en prenant exactement 1 octet par caractère.
La table la plus utilisée en Europe a été latin-1, remplacée par latin-9 pour introduire notamment l'euro.
Exemples
- l'espace est un caractère qui possède une valeur (32 10 ou 20 16) et prend donc un octet en mémoire à ces tables.
- le A est un caractère qui possède une valeur (65 10 ou 41 16) et prend donc un octet en mémoire à ces tables.
- le passage à la ligne (ou LF pour Line Feed) est un caractère qui possède une valeur (10 10 ou 0A 16) et prend donc un octet en mémoire à ces tables. On le représente parfois sous la forme d'une flèche ↲ ou plus généralemente par \n
Remarque sur le protocole HTTP : de façon à ne pas créer des problèmes de compréhension sur les requêtes HTTP et les répondes HTTP, on transmet uniquement des caractères ASCII. Cela évite les problèmes de décodage erroné. Exemple ici avec une requête GET envoyé par Firefox à un serveur :
GET /act/archi/communication-client-serveur/ HTTP/1.1↲
Host: www.infoforall.fr↲
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0↲
On voit bien que ce message ne contient que de l'ASCII. De cete façon, quelque soit la table 1 octet utilisée, il n'y a pas possibilité de se tromper puisqu'elles sont toutes compatibles ASCII sur leur première partie.
✎ 10° Estimer le nombre nécessaire d'octets pour encoder ce texte en latin-1. Pensez bien à tous les caractères, même les caractères "cachés".
Bon, alors
combien d'octets pour
stocker
ça ?
Ce nombre change-t-il si on utilise une autre table "1 octet" ?
4 - Décodage avec Python
Nous avons vu comment encoder avec la méthode encode. Il est temps de parvenir à savoir décoder avec la méthode ... decode.
Méthode des bytes : decode
On peut créer un string en utilisant sur un objet bytes la méthode decode. Cette méthode attend au moins un paramètre de type string contenant le nom de la table d'encodage à utiliser.
La méthode renvoie un objet de type str.
Un exemple avec un texte qu'on avait encodé en latin9, également nommé iso8859_15 sur ma machine. Voir la question 07 pour voir le nom qu'elle peut porter sur la votre.
>>> texte = b"Cet article co\xFBte\x2020\xA3.".decode('latin9')
>>> texte
'Cet article coûte 20£.'
>>> texte = b"Cet article co\xFBte\x2020\xA3.".decode('iso8859_15')
>>> texte
'Cet article coûte 20£.'
Pourquoi un tel résultat ? Il suffit d'aller voir la valeur des caractères en hexadécimal pour ceux précédé de \x.
\xFB
pourû
.\x20
pour\xA3
pour£
.
✎ 11° Que va contenir texte dans l'exemple ci-dessous ?
Attention, il y a une différence par rapport à l'exemple du dessus.
>>> texte = b"Cet article co\xFBte\x2020\xA4.".decode('iso8859_15')
>>> texte
? votre réponse ?
Là où c'était vraiment pénible, c'était donc lorsqu'on ne connaissait pas l'encode d'un texte. On devait faire au hasard, en utilisant l'encodage le plus probable.
Voici ainsi un exemple où on dispose de la suite d'octets 160, 161, 162, 164... qu'on décode avec différentes tables :
Création d'un contenu bytes (octets)
>>> t = [160, 161, 162, 163, 164, 165]
>>> octets = bytes(t)
>>> octets
b'\xa0\xa1\xa2\xa3\xa4\xa5'
Décodage de ces octets en utilisant différentes tables...
>>> print(octets.decode('latin-1'))
¡¢£¤¥
>>> print(octets.decode('latin9'))
¡¢£€¥
>>> print(octets.decode('thai'))
กขฃคฅ
>>> print(octets.decode('iso8859_10'))
ĄĒĢĪĨ
>>> print(octets.decode('iso8859_11'))
กขฃคฅ
>>> print(octets.decode('iso8859_13'))
”¢£¤„
>>> print(octets.decode('iso8859_14'))
Ḃḃ£Ċċ
>>> print(octets.decode('iso8859_15'))
¡¢£€¥
>>> print(octets.decode('iso8859_16'))
ĄąŁ€„
Vous devriez voir que pour un même contenu en octets, le texte obtenu est bien différents selon le choix de la table utilisée pour décoder. Il fallait donc trouver des moyens clairs et précis d'indiquer la table qui avait été utilisée pour encoder le texte. Malgré ça, le risque d'erreur était encore très grand.
5 - UNICODE
UNICODE
Principe
UNICODE n'est pas une table d'encodage à proprement parler : UNICODE n'impose rien au sujet de la façon de représenter le nombre UNICODE en mémoire.
Il s'agit juste d'une immense table associant un numéro à un glyphe (un caractère).
Exemples
A est associé à 6510 (compatible ASCII)
a est associé à 9710 (compatible ASCII)
ᎈ est associé à 50010
⟘ est associé à 1020010
😀 est associé à 12851210
Contenu
UNICODE regroupe tous les caractères et assimilés qu'utilise l'humanité, ou presque : les caractères des langues connues, les caractères scientifiques, des éléments graphiques mais également des icones comme les emote-icons.
Au moment où j'ai écrit cette partie, nous en étions à Unicode 13.0, version qui contient 143 859 caractères différents.
Les caractères UNICODE sont classés en bloc thématique contenant 65536 caractères. Il existe donc beaucoup de valeurs non utilisées puisque les blocs ne sont pas totalement plein loin de là : les 143 859 glyphes de la version 13 sont associés à des numéros compris entre 0 et 16 842 751.
Le but est de garantir une durée de vie énorme au système en pouvant rajouter un nombre très important de valeurs.
Plus de renseignements et une visualisation de tous les caractères, sur le site d'UNICODE.
La page correspondante de Wikipedia est très bien réalisée également WIKIPEDIA.
Voici quelques minces extraits des caractères présents dans UNICODE. Pour visualiser le numéro en décimal, il suffit de rester stationnaire au dessus du caractère.
...0 à 255 : identique aux valeurs latin-1...
Numéros 0-255 | ||||||||||||||||
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ |
0x1_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ |
0x2_ | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
0x3_ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
0x4_ | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
0x5_ | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
0x6_ | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
0x7_ | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ¤¤¤ |
0x8_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ |
0x9_ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ | ¤¤¤ |
0xA_ | ¤¤¤ | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | ¤¤¤ | ® | ¯ |
0xB_ | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ |
0xC_ | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï |
0xD_ | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß |
0xE_ | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï |
0xF_ | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ |
...Numéros 256-511...
Numéros 256-511 | ||||||||||||||||
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x10_ | Ā | ā | Ă | ă | Ą | ą | Ć | ć | Ĉ | ĉ | Ċ | ċ | Č | č | Ď | ď |
0x11_ | Đ | đ | Ē | ē | Ĕ | ĕ | Ė | ė | Ę | ę | Ě | ě | Ĝ | ĝ | Ğ | ğ |
0x12_ | Ġ | ġ | Ģ | ģ | Ĥ | ĥ | Ħ | ħ | Ĩ | ĩ | Ī | ī | Ĭ | ĭ | Į | į |
0x13_ | İ | ı | IJ | ij | Ĵ | ĵ | Ķ | ķ | ĸ | Ĺ | ĺ | Ļ | ļ | Ľ | ľ | Ŀ |
0x14_ | ŀ | Ł | ł | Ń | ń | Ņ | ņ | Ň | ň | ʼn | Ŋ | ŋ | Ō | ō | Ŏ | ŏ |
0x15_ | Ő | ő | Œ | œ | Ŕ | ŕ | Ŗ | ŗ | Ř | ř | Ś | ś | Ŝ | ŝ | Ş | ş |
0x16_ | Š | š | Ţ | ţ | Ť | ť | Ŧ | ŧ | Ũ | ũ | Ū | ū | Ŭ | ŭ | Ů | ů |
0x17_ | Ű | ű | Ų | ų | Ŵ | ŵ | Ŷ | ŷ | Ÿ | Ź | ź | Ż | ż | Ž | ž | ſ |
0x18_ | ƀ | Ɓ | Ƃ | ƃ | Ƅ | ƅ | Ɔ | Ƈ | ƈ | Ɖ | Ɗ | Ƌ | ƌ | ƍ | Ǝ | Ə |
0x19_ | Ɛ | Ƒ | ƒ | Ɠ | Ɣ | ƕ | Ɩ | Ɨ | Ƙ | ƙ | ƚ | ƛ | Ɯ | Ɲ | ƞ | Ɵ |
0x1A_ | Ơ | ơ | Ƣ | ƣ | Ƥ | ƥ | Ʀ | Ƨ | ƨ | Ʃ | ƪ | ƫ | Ƭ | ƭ | Ʈ | Ư |
0x1B_ | ư | Ʊ | Ʋ | Ƴ | ƴ | Ƶ | ƶ | Ʒ | Ƹ | ƹ | ƺ | ƻ | Ƽ | ƽ | ƾ | ƿ |
0x1C_ | ǀ | ǁ | ǂ | ǃ | DŽ | Dž | dž | LJ | Lj | lj | NJ | Nj | nj | Ǎ | ǎ | Ǐ |
0x1D_ | ǐ | Ǒ | ǒ | Ǔ | ǔ | Ǖ | ǖ | Ǘ | ǘ | Ǚ | ǚ | Ǜ | ǜ | ǝ | Ǟ | ǟ |
0x1E_ | Ǡ | ǡ | Ǣ | ǣ | Ǥ | ǥ | Ǧ | ǧ | Ǩ | ǩ | Ǫ | ǫ | Ǭ | ǭ | Ǯ | ǯ |
0x1F_ | ǰ | DZ | Dz | dz | Ǵ | ǵ | Ƕ | Ƿ | Ǹ | ǹ | Ǻ | ǻ | Ǽ | ǽ | Ǿ | ǿ |
...Numéros 512-767...
Numéros 512-767 | ||||||||||||||||
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x20_ | Ȁ | ȁ | Ȃ | ȃ | Ȅ | ȅ | Ȇ | ȇ | Ȉ | ȉ | Ȋ | ȋ | Ȍ | ȍ | Ȏ | ȏ |
0x21_ | Ȑ | ȑ | Ȓ | ȓ | Ȕ | ȕ | Ȗ | ȗ | Ș | ș | Ț | ț | Ȝ | ȝ | Ȟ | ȟ |
0x22_ | Ƞ | ȡ | Ȣ | ȣ | Ȥ | ȥ | Ȧ | ȧ | Ȩ | ȩ | Ȫ | ȫ | Ȭ | ȭ | Ȯ | ȯ |
0x23_ | Ȱ | ȱ | Ȳ | ȳ | ȴ | ȵ | ȶ | ȷ | ȸ | ȹ | Ⱥ | Ȼ | ȼ | Ƚ | Ⱦ | ȿ |
0x24_ | ɀ | Ɂ | ɂ | Ƀ | Ʉ | Ʌ | Ɇ | ɇ | Ɉ | ɉ | Ɋ | ɋ | Ɍ | ɍ | Ɏ | ɏ |
0x25_ | ɐ | ɑ | ɒ | ɓ | ɔ | ɕ | ɖ | ɗ | ɘ | ə | ɚ | ɛ | ɜ | ɝ | ɞ | ɟ |
0x26_ | ɠ | ɡ | ɢ | ɣ | ɤ | ɥ | ɦ | ɧ | ɨ | ɩ | ɪ | ɫ | ɬ | ɭ | ɮ | ɯ |
0x27_ | ɰ | ɱ | ɲ | ɳ | ɴ | ɵ | ɶ | ɷ | ɸ | ɹ | ɺ | ɻ | ɼ | ɽ | ɾ | ɿ |
0x28_ | ʀ | ʁ | ʂ | ʃ | ʄ | ʅ | ʆ | ʇ | ʈ | ʉ | ʊ | ʋ | ʌ | ʍ | ʎ | ʏ |
0x29_ | ʐ | ʑ | ʒ | ʓ | ʔ | ʕ | ʖ | ʗ | ʘ | ʙ | ʚ | ʛ | ʜ | ʝ | ʞ | ʟ |
0x2A_ | ʠ | ʡ | ʢ | ʣ | ʤ | ʥ | ʦ | ʧ | ʨ | ʩ | ʪ | ʫ | ʬ | ʭ | ʮ | ʯ |
0x2B_ | ʰ | ʱ | ʲ | ʳ | ʴ | ʵ | ʶ | ʷ | ʸ | ʹ | ʺ | ʻ | ʼ | ʽ | ʾ | ʿ |
0x2C_ | ˀ | ˁ | ˂ | ˃ | ˄ | ˅ | ˆ | ˇ | ˈ | ˉ | ˊ | ˋ | ˌ | ˍ | ˎ | ˏ |
0x2D_ | ː | ˑ | ˒ | ˓ | ˔ | ˕ | ˖ | ˗ | ˘ | ˙ | ˚ | ˛ | ˜ | ˝ | ˞ | ˟ |
0x2E_ | ˠ | ˡ | ˢ | ˣ | ˤ | ˥ | ˦ | ˧ | ˨ | ˩ | ˪ | ˫ | ˬ | ˭ | ˮ | ˯ |
0x2F_ | ˰ | ˱ | ˲ | ˳ | ˴ | ˵ | ˶ | ˷ | ˸ | ˹ | ˺ | ˻ | ˼ | ˽ | ˾ | ˿ |
...Numéros 8704-8959...
Numéros 8704-8959 | ||||||||||||||||
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x220_ | ∀ | ∁ | ∂ | ∃ | ∄ | ∅ | ∆ | ∇ | ∈ | ∉ | ∊ | ∋ | ∌ | ∍ | ∎ | ∏ |
0x221_ | ∐ | ∑ | − | ∓ | ∔ | ∕ | ∖ | ∗ | ∘ | ∙ | √ | ∛ | ∜ | ∝ | ∞ | ∟ |
0x222_ | ∠ | ∡ | ∢ | ∣ | ∤ | ∥ | ∦ | ∧ | ∨ | ∩ | ∪ | ∫ | ∬ | ∭ | ∮ | ∯ |
0x223_ | ∰ | ∱ | ∲ | ∳ | ∴ | ∵ | ∶ | ∷ | ∸ | ∹ | ∺ | ∻ | ∼ | ∽ | ∾ | ∿ |
0x224_ | ≀ | ≁ | ≂ | ≃ | ≄ | ≅ | ≆ | ≇ | ≈ | ≉ | ≊ | ≋ | ≌ | ≍ | ≎ | ≏ |
0x225_ | ≐ | ≑ | ≒ | ≓ | ≔ | ≕ | ≖ | ≗ | ≘ | ≙ | ≚ | ≛ | ≜ | ≝ | ≞ | ≟ |
0x226_ | ≠ | ≡ | ≢ | ≣ | ≤ | ≥ | ≦ | ≧ | ≨ | ≩ | ≪ | ≫ | ≬ | ≭ | ≮ | ≯ |
0x227_ | ≰ | ≱ | ≲ | ≳ | ≴ | ≵ | ≶ | ≷ | ≸ | ≹ | ≺ | ≻ | ≼ | ≽ | ≾ | ≿ |
0x228_ | ⊀ | ⊁ | ⊂ | ⊃ | ⊄ | ⊅ | ⊆ | ⊇ | ⊈ | ⊉ | ⊊ | ⊋ | ⊌ | ⊍ | ⊎ | ⊏ |
0x229_ | ⊐ | ⊑ | ⊒ | ⊓ | ⊔ | ⊕ | ⊖ | ⊗ | ⊘ | ⊙ | ⊚ | ⊛ | ⊜ | ⊝ | ⊞ | ⊟ |
0x22A_ | ⊠ | ⊡ | ⊢ | ⊣ | ⊤ | ⊥ | ⊦ | ⊧ | ⊨ | ⊩ | ⊪ | ⊫ | ⊬ | ⊭ | ⊮ | ⊯ |
0x22B_ | ⊰ | ⊱ | ⊲ | ⊳ | ⊴ | ⊵ | ⊶ | ⊷ | ⊸ | ⊹ | ⊺ | ⊻ | ⊼ | ⊽ | ⊾ | ⊿ |
0x22C_ | ⋀ | ⋁ | ⋂ | ⋃ | ⋄ | ⋅ | ⋆ | ⋇ | ⋈ | ⋉ | ⋊ | ⋋ | ⋌ | ⋍ | ⋎ | ⋏ |
0x22D_ | ⋐ | ⋑ | ⋒ | ⋓ | ⋔ | ⋕ | ⋖ | ⋗ | ⋘ | ⋙ | ⋚ | ⋛ | ⋜ | ⋝ | ⋞ | ⋟ |
0x22E_ | ⋠ | ⋡ | ⋢ | ⋣ | ⋤ | ⋥ | ⋦ | ⋧ | ⋨ | ⋩ | ⋪ | ⋫ | ⋬ | ⋭ | ⋮ | ⋯ |
0x22F_ | ⋰ | ⋱ | ⋲ | ⋳ | ⋴ | ⋵ | ⋶ | ⋷ | ⋸ | ⋹ | ⋺ | ⋻ | ⋼ | ⋽ | ⋾ | ⋿ |
...Numéros 63744-63999...
Numéros 63744-63999 | ||||||||||||||||
_0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0xF90_ | 豈 | 更 | 車 | 賈 | 滑 | 串 | 句 | 龜 | 龜 | 契 | 金 | 喇 | 奈 | 懶 | 癩 | 羅 |
0xF91_ | 蘿 | 螺 | 裸 | 邏 | 樂 | 洛 | 烙 | 珞 | 落 | 酪 | 駱 | 亂 | 卵 | 欄 | 爛 | 蘭 |
0xF92_ | 鸞 | 嵐 | 濫 | 藍 | 襤 | 拉 | 臘 | 蠟 | 廊 | 朗 | 浪 | 狼 | 郎 | 來 | 冷 | 勞 |
0xF93_ | 擄 | 櫓 | 爐 | 盧 | 老 | 蘆 | 虜 | 路 | 露 | 魯 | 鷺 | 碌 | 祿 | 綠 | 菉 | 錄 |
0xF94_ | 鹿 | 論 | 壟 | 弄 | 籠 | 聾 | 牢 | 磊 | 賂 | 雷 | 壘 | 屢 | 樓 | 淚 | 漏 | 累 |
0xF95_ | 縷 | 陋 | 勒 | 肋 | 凜 | 凌 | 稜 | 綾 | 菱 | 陵 | 讀 | 拏 | 樂 | 諾 | 丹 | 寧 |
0xF96_ | 怒 | 率 | 異 | 北 | 磻 | 便 | 復 | 不 | 泌 | 數 | 索 | 參 | 塞 | 省 | 葉 | 說 |
0xF97_ | 殺 | 辰 | 沈 | 拾 | 若 | 掠 | 略 | 亮 | 兩 | 凉 | 梁 | 糧 | 良 | 諒 | 量 | 勵 |
0xF98_ | 呂 | 女 | 廬 | 旅 | 濾 | 礪 | 閭 | 驪 | 麗 | 黎 | 力 | 曆 | 歷 | 轢 | 年 | 憐 |
0xF99_ | 戀 | 撚 | 漣 | 煉 | 璉 | 秊 | 練 | 聯 | 輦 | 蓮 | 連 | 鍊 | 列 | 劣 | 咽 | 烈 |
0xF9A_ | 裂 | 說 | 廉 | 念 | 捻 | 殮 | 簾 | 獵 | 令 | 囹 | 寧 | 嶺 | 怜 | 玲 | 瑩 | 羚 |
0xF9B_ | 聆 | 鈴 | 零 | 靈 | 領 | 例 | 禮 | 醴 | 隸 | 惡 | 了 | 僚 | 寮 | 尿 | 料 | 樂 |
0xF9C_ | 燎 | 療 | 蓼 | 遼 | 龍 | 暈 | 阮 | 劉 | 杻 | 柳 | 流 | 溜 | 琉 | 留 | 硫 | 紐 |
0xF9D_ | 類 | 六 | 戮 | 陸 | 倫 | 崙 | 淪 | 輪 | 律 | 慄 | 栗 | 率 | 隆 | 利 | 吏 | 履 |
0xF9E_ | 易 | 李 | 梨 | 泥 | 理 | 痢 | 罹 | 裏 | 裡 | 里 | 離 | 匿 | 溺 | 吝 | 燐 | 璘 |
0xF9F_ | 藺 | 隣 | 鱗 | 麟 | 林 | 淋 | 臨 | 立 | 笠 | 粒 | 狀 | 炙 | 識 | 什 | 茶 | 刺 |
Et on encode comment ?
L'encodage en octets n'est pas géré par UNICODE : c'est une simple correspondance numéro - caractère. Et c'est sa force : même si on change la façon dont les numéros sont mémorisés sous forme d'octets, on gardera la possibilité de lire les anciens contenus.
Actuellement, les encodages nommés UTF-8, UTF-16, UTF-32 se chargent de l'aspect transformation en octets justement.
Retro-compatibilité
Pour maintenir une retro-compatibilité, les valeurs UNICODE des valeurs 0 à 127 correspondent exactement aux valeurs d'encodage de la table ASCII.
Pour maintenir une certaine retro-compatibilité, les valeurs UNICODE des valeurs 128 à 255 correspondent exactement aux valeurs d'encodage de la table latin-1.
Les caractères présents dans les autres tables sont associés à un numéro supérieur à 255.
Justement, Python utilise directement à l'interne ce code pour gérer ces caractères. C'est pour cela que vous pourriez utiliser des noms de variables ou des fonctions en utlisant les caractères de n'importe quelle langue.
UNICODE et PYTHON : fonctions natives ord et chr
La fonction native chr renvoie le caractère UNICODE correspondant au nombre décimal décimal fourni en argument.
>>> chr(65)
'A'
>>> chr(10000)
'✐'
>>> chr(20000)
'丠'
La fonction native ord fait l'inverse : elle renvoie la valeur UNICODE correspondant au caractère fourni en argument.
>>> ord('A')
65
>>> ord('✐')
10000
>>> ord('丠')
20000
Et en hexadécimal ?
C'est pareil, il suffit de dire à Python que vous fournissez un nombre en base 16 :
>>> hex(65)
'0x41'
>>> chr(0x41)
'A'
UNICODE et HTML
On peut afficher très facilement de l'UNICODE dans HTML.
Il suffit de taper 
où FFFFF
correspond au numéro en hexadécimal que vous aurez trouvé sur une page décrivant ces caractères.
On obtient 🧙 en tapant 🧙
.
On obtient 🧚 en tapant 🧚
.
On obtient 🐲 en tapant 🐲
.
Si vous voulez fournir le numéro en décimal, c'est pareil, mais on ne met pas le x qui veut dire hexadécimal :
On obtient 🧙 en tapant 🧙
.
Pourquoi ? Simplement car 1F9D616 = 12949710.
Si vous voulez en voir plus, Wiipédia a des pages assez claires et bien faites sur le sujet. exemple
12° Créer un programme qui permet d'afficher les caractères UNICODE de l'invervalle [1000;1100].
...CORRECTION...
J'espère que vous avez trouvé tout seul...
Une correction pour la forme.
1
2 | for valeur in range(1000,1101):
print(chr(valeur))
|
Et le résultat attendu :
Ϩ
ϩ
Ϫ
ϫ
Ϭ
ϭ
Ϯ
ϯ
ϰ
ϱ
ϲ
ϳ
ϴ
ϵ
϶
Ϸ
ϸ
Ϲ
Ϻ
ϻ
ϼ
Ͻ
Ͼ
Ͽ
Ѐ
Ё
Ђ
Ѓ
Є
Ѕ
І
Ї
Ј
Љ
Њ
Ћ
Ќ
Ѝ
Ў
Џ
А
Б
В
Г
Д
Е
Ж
З
И
Й
К
Л
М
Н
О
П
Р
С
Т
У
Ф
Х
Ц
Ч
Ш
Щ
Ъ
Ы
Ь
Э
Ю
Я
а
б
в
г
д
е
ж
з
и
й
к
л
м
н
о
п
р
с
т
у
ф
х
ц
ч
ш
щ
ъ
ы
ь
Mais on aurait pu demander de 9800 à 9900 :
♈
♉
♊
♋
♌
♍
♎
♏
♐
♑
♒
♓
♔
♕
♖
♗
♘
♙
♚
♛
♜
♝
♞
♟
♠
♡
♢
♣
♤
♥
♦
♧
♨
♩
♪
♫
♬
♭
♮
♯
♰
♱
♲
♳
♴
♵
♶
♷
♸
♹
♺
♻
♼
♽
♾
♿
⚀
⚁
⚂
⚃
⚄
⚅
⚆
⚇
⚈
⚉
⚊
⚋
⚌
⚍
⚎
⚏
⚐
⚑
⚒
⚓
⚔
⚕
⚖
⚗
⚘
⚙
⚚
⚛
⚜
⚝
⚞
⚟
⚠
⚡
⚢
⚣
⚤
⚥
⚦
⚧
⚨
⚩
⚪
⚫
Attention par contre, selon les supports, les glyphes colorés sont parfois indisponibles.
C'est bien gentil tout ça mais ça n'explique pas concrétement comment encoder les caractères.
✎ 13° Fournir le calcul à faire pour montrer qu'avec 3 octets (24 bits donc), on ne peut pas encoder la valeur extrème actuelle d'UNICODE 16 842 751 10.
✎ 14° Fournir le calcul à faire pour montrer qu'avec 4 octets (32 bits donc), on peut encoder plus de 4 milliards de caractères.
En nous arrivons au problème majeur de l'UNICODE : comment parvenir à encoder correctement tous ces caractères.
Imaginons qu'on décide d'utiliser 4 octets pour chaque caractère. Cela permet d'aller jusqu'à 4 milliards de caractères, nous avons donc plus de marge qu'avec les tables d'un octet...
Cet encodage brut se nomme UTF-32.
D'où vient ce nom ? De Universal Character Set Transformation Format 32 bits. Ca tombe bien 32 bits, ça donne 4 octets.
Le problème d'UTF-32 vient de la taille des fichiers : ils seraient globalement 4 fois plus lourd à stocker qu'avec les encodages 1 octet, puisqu'il faudrait 4 octets par caractère.
15° Expliquer en quelques mots pourquoi on obtient bien à peu près quatre fois plus en utilisant l'encodage UTF-32 plutôt que l'encodade latin-1.
1
2
3
4
5
6
7 |
|
31
128
Pourquoi y-a-t-il quelques octets en plus ?
Il s'agit d'octets de valeurs connus qui permettent de reconnaitre qu'il s'agit d'un texte encodé en UTF. On leur donne le nom de BOM.
Le BOM est composé de 2 octets en UTF-16 et de 4 octets en UTF-32.
Si on reprend l'exemple de la question précédente : nous avons 31 caractères à encoder en UTF-32 dont 31 * 4 = 124. Si on rajoute les 4 octets du BOM, on retombe bien sur 128.
Voir la FAQ en bas de page et en fin de séance si ça vous intéresse.
Un fichier-texte de 100 000 caractères encodé en latin-1 prendrait 100 ko de place mémoire sans compression.
Le même fichier encodé avec UTF-32 occuperait 400 ko (+ 4 petits octets de BOM)
Et c'est qu'intervient le fameux UTF-8.
6 - UTF-8
UTF-8
Idée générale
L'idée générale derrière UTF-8 est de pouvoir encoder les numéros UNICODE en prenant moins que 4 octets par caractère dans la majorité des cas.
- Les caractères courantes (ASCII) sont encodés en utilisant uniquement 1 octet.
- Les caractères assez courants sont encodés en utilisant 2 octets
- Les caractères rares sont encodés en utilisant 3 octets
- Les derniers caractères en utilisant 4 octets s'il le faut vraiment
>>> list("A".encode('utf-8'))
[65]
>>> list("é".encode('utf-8'))
[195, 169]
>>> list("✎".encode('utf-8'))
[226, 156, 142]
UTF-8 veut dire donc que certains caractères prennent 8 bits, soit 1 octet. Pour les autres, c'est plus.
Ce sont les caractères courants dans la plupart des langages occidentaux (ceux de la table ASCII donc) qui sont encodés sur 1 octet. D'où la présence d'autres encodages. UTF-8 est un standard, mais pas LE standard universel.
UTF-8 : le standard actuel
Il est aujourd'hui l'encodage par défaut des systèmes UNIX compatibles (Linux, MacOS) et plus de 95% des pages Web sont encodées en UTF-8.
Nous n'allons pas rentrer dans le détail de la norme ici.
16° Quelle place mémoire prendrait le texte suivant en étant encodé en ASCII (via latin-1), en UTF-8 puis en UTF-32 ?
>>> texte = "ABCDE"
...CORRECTION...
Il ne s'agit que de caractères ASCII.
Il y a 5 caractères.
En ASCII (via latin-1) : 5 octets.
En UTF-8 : 5 octets.
En UTF-32 : 20 octets + 4 octets de BOM : 24 octets.
17° En UTF-8, quelle place mémoire occupe le caractère 'à' en UTF-8 ? Et pour '♥' ?
>>> octets = 'à'.encode('utf8')
>>> octets
b'\xc3\xa0'
>>> list("à".encode('utf-8'))
[195, 160]
>>> octets = '♥'.encode('utf8')
>>> octets
b'\xe2\x99\xa5'
>>> list("♥".encode('utf-8'))
[226, 153, 165]
...CORRECTION...
2 pour le à : il n'appartient pas à ASCII mais reste assez courant.
3 pour le coeur : il est d'usage rare.
Il nous reste à avoir une explication sur l'image d'introduction. Vous avez maintenant toutes les cartes en main pour comprendre pourquoi le é s'affiche mal sur les images suivantes :
✎ 18° Expliquer le plus clairement possible pourquoi le "é"
encodé en UTF-8 se transforme en deux caractères "é"
lorsqu'on décode les octets avec latin-1.
>>> octets = "é".encode('utf-8')
>>> octets
b'\xc3\xa9'
>>> texte = octets.decode('latin-1')
>>> texte
'é'
✎ 19° Combien d'octets faut-il pour encoder le texte suivant en UTF-8 : "L'encodage UTF-8 a été publié officiellement en 1996, 5 ans après la création du Web."
.
Comparer avec un encodage en latin-1 (ou ISO-8859-1).
Les QCM pour savoir ce qu'il faut retenir pour la fin.
✎ 20° Répondre aux questions suivantes :
Quel a été le premier encodage standardisé des caractères ?
- A : ASCII
- B : cp-437
- C : latin-1 ou iso8859_1
- D : UTF-8
Combien d'associations valeurs-caractères peuvent encoder au maximum les tables du type latin-1 (ou ISO-8859-1) ?
- A : 127
- B : 128
- C : 255
- D : 256
UNICODE est
- A : un encodage qui remplace maintenant latin-1 (ou ISO-8859-1)
- B : une simple association d'un entier et d'un caractère
- C : un encodage sur 1 octet
- D : un encodage sur 4 octets
UTF-8 est
- A : une autre façon d'encoder les tables 1 octet (donc 8 bits)
- B : un encodage basé sur UNICODE dans lequel les caractères prennent tous 8 octets
- C : la 8e version de l'encodage UTF, incluant le symbole monétaire EURO
- D : un encodage basé sur UNICODE dans lequel les caractères prennent de 1 à 4 octets
7 - Bilan
Que devez-vous savoir au final :
- Comment est représenter d’un texte en machine de façon générale ?
- Qu'est-ce que l'encodage ASCII ?,
- Qu'est-ce que l'encodage ISO-8859-1 ?,
- Qu'est-ce que le système UNICODE ?,
- Qu'est-ce que l'encodage UTF-8 ?,
- Comment trouver la valeur unicode d'un caractère en Python ?,
- Comment trouver afficher un caractère à l'aide de sa valeur UNICODE en Python ?,
- Comment trouver afficher un caractère à l'aide de sa valeur UNICODE en HTML (hexa ou décimal) ?,
- Comment encoder sous forme d'octets (bytes) un texte UNICODE en Python en respectant un encodage précis ?,
- Comment décoder des octets (bytes) en texte connaissant l'encodage utilisé en Python ?,
Si vous avez encore un peu de temps, voici quelques questions bonus : elles vous permettront de comprendre un peu comment fonctionne UTF-8. Mais attention : rien d'exigible pour la NSI.
Bonus 1° Voici un exemple de code permettant de trouver l'encodage UTF-8 d'une chaîne de 5 caractères purement ASCII ici. Remarquez bien que tous les bits commencent à 0 : c'est comme cela que le système sait qu'il s'agit de caractère encodé sur un octet uniquement.
1
2
3
4
5
6
7 | texte = "ABCDE"
octets = texte.encode('utf-8')
suite_en_decimal = list(octets)
suite_en_binaire = [bin(octet)[2:].rjust(8,'0') for octet in octets]
print(suite_en_decimal)
print(suite_en_binaire)
|
Vous devriez trouver
[65, 66, 67, 68, 69]
['01000001', '01000010', '01000011', '01000100', '01000101']
On obtient bien 5 octets.
Bonus 2° Même chose mais avec une chaîne de 11 caractères dont un caractère non ASCII : le é.
1
2
3
4
5
6
7 | texte = "C'est écrit"
octets = texte.encode('utf-8')
suite_en_decimal = list(octets)
suite_en_binaire = [bin(octet)[2:].rjust(8,'0') for octet in octets]
print(suite_en_decimal)
print(suite_en_binaire)
|
Voici le résultat que vous devriez obtenir :
[67, 39, 101, 115, 116, 32, 195, 169, 99, 114, 105, 116]
['01000011', '00100111', '01100101', '01110011', '01110100', '00100000',
'11000011', '10101001',
'01100011', '01110010', '01101001', '01110100']
Le é est donc encodé avec ces deux octets :
'11000011', '10101001'
Questions
- Combien d'octets pour encoder le é ?
- Combien de 1 successifs au début du premier octet encodant le é ?
- Dans UTF, les octets supplémentaires possèdent une sorte de détection d'erreur : tous les octets supplémentaires commencent par la séquence 10 : pourquoi peut-on dire que le second octet encodant le é est à priori valide ?
...CORRECTION...
Le é nécessite 2 octets.
Et justement, le premier octet commence par une séquence de 2 bit à 1 : c'est comme cela que le système sait que ce caractère nécessite la lecture de deux octets en tout.
Le second octet est valide puisqu'il commence bien par une séquence 10
.
Bonus 3° Même chose mais avec une chaîne comprtant quelques caractères encore plus rare.
1
2
3
4
5
6
7 | texte = "Voici un ♥"
octets = texte.encode('utf-8')
suite_en_decimal = list(octets)
suite_en_binaire = [bin(octet)[2:].rjust(8,'0') for octet in octets]
print(suite_en_decimal)
print(suite_en_binaire)
|
Voici le résultat que vous devriez obtenir :
[86, 111, 105, 99, 105, 32, 117, 110, 32, 226, 153, 165]
['01010110', '01101111', '01101001', '01100011',
'01101001', '00100000', '01110101', '01101110',
'00100000', '11100010', '10011001', '10100101']
Le ♥ est donc encodé avec ces trois octets :
'11100010', '10011001', '10100101']
Questions
- Combien d'octets pour encoder le ♥ ?
- Combien de 1 successifs au début du premier octet encodant le ♥ ?
- Dans UTF, les octets supplémentaires possèdent une sorte de détection d'erreur : tous les octets supplémentaires commencent par la séquence 10 : pourquoi peut-on dire que les octets suivants sont à priori valides ?
...CORRECTION...
Le ♥ nécessite 3 octets.
Et justement, le premier octet commence par une séquence de 3 bit à 1 : c'est comme cela que le système sait que ce caractère nécessite la lecture de trois octets en tout.
Les octets suivants sont valides puisqu'ils commencent bien par une séquence 10
.
8 - FAQ
Et UTF-16, c'est quoi cet encodage ?
L'encodage UTF-16 est utilisé notamment dans les pays asiatiques. Tous les caractères sont encodés sur 2 octets, 3 ou 4 octets. Il permet de placer beaucoup plus de caractères sur la zone de deux octets.
Cette encodage est donc plus performant que l'UTF-8 pour les langages qui utilisent des caractères rares présents dans la zone des caractères 3 octets dans UTF-8 : la plupart des caractères 3 octets sont des caractères 2 octets en UTF-16.
D'ou viennent les quelques octets en plus en UTF-32 par rapport aux tables 1 octet ?
Il s'agit des octets du BOM : Byte Order Mark.
Comme on doit encoder les valeurs sur plus d'un octet, il faut savoir quel octet va être multiplié par 1 (20), quel octet va être multiplié par 256 (28), quel octet va être multiplié par 65536 (216)...
Exemple : on veut stocker 65538.
On va donc décomposer de cette façon 65536*1
+ 256*0
+ 1*2
.
Il faudra donc utiliser 3 octets valant 1
, 0
et 2
. L'octet 1
représente ici l'octet de poids fort.
Le problème ?
Dans la mémoire, le système a deux possibilités :
- BIG ENDIAN : l'octet de poids fort est stocké d'abord :
1-0-2
ou - LITTLE ENDIAN : on stocke d'abord l'octet de poids faible :
2-0-1
...
Comment savoir alors ?
C'est là qu'intervient le BOM : on place volontairement une suite d'octets connus FE
16-FF
16 en début du fichier texte.
Lorsque le système va lire le début du fichier, il lira donc
- soit d'abord l'octet
FE
16 : on comprend qu'il faudra utiliser BIG ENDIAN. - soit d'abord l'octet
FF
16 : on comprend qu'il faudra utiliser LITTLE ENDIAN.
Exemple en UTF-16 : 2 octets pour le BOM
>>> o = [hex(v) for v in list("ABCD".encode("utf-16"))]
>>> o
['0xff', '0xfe',
'0x41', '0x0',
'0x42', '0x0',
'0x43', '0x0',
'0x44', '0x0']
On voit ici qu'on est en LITTLE ENDIAN :
- Le BOM est dans l'ordre
FF
puisFE
- Le A de code
0041
16 est dans l'ordre41
puis00
- ...
Exemple en UTF-32 : 4 octets pour le BOM
>>> o = [hex(v) for v in list("ABCD".encode("utf-32"))]
>>> o
['0xff', '0xfe', '0x0', '0x0',
'0x41', '0x0', '0x0', '0x0',
'0x42', '0x0', '0x0', '0x0',
'0x43', '0x0', '0x0', '0x0',
'0x44', '0x0', '0x0', '0x0']
On voit ici qu'on est en LITTLE ENDIAN :
- Le BOM est dans l'ordre
FF
puisFE
puis0
puis0
- Le A de code
0041
16 est dans l'ordre41
puis00
00
00
- ...
Comment sait-on qu'on doit lire 1, 2 ou 4 octets lorsqu'on lit un texte encodé en UTF-8 ?
UN OCTET : caractères courants (dans notre culture occidentale)
Le contenu binaire de la forme : 0xxx xxxx
où x
représente un bit quelconque.
Le bit de poids fort est 0
: cela indique en UTF-8 que le caractère est encodé sur un seul octet :
Il y a 7 x
: on peut encoder 27 caractères : ceux de la table ASCII.
Exemple :
Le code ASCII du A est 65 en décimal et en binaire : 100 0001 .
Son code UTF-8 est donc obtenu en rajoutant 0
devant : 0100 0001
.
Il correspond donc toujours à un octet donnant 65 en décimal. C'est un A.
DEUX OCTETS : caractères un peu moins courants
Les deux octets ont cette structure : 110x xxxx - 10xx xxxx
.
Le premier octet de la suite commence par 11
suivi d'un bit 0
: cela veut dire qu'il faudra deux octets pour trouver la valeur UNICODE du caractère.
Le deuxième octet commence par 10
Il y a 11 x : on peut encoder 211 caractères supplémentaires.
Exemple :
Le "é" est encodé en UTF-8 par 1100 0011
1010 1001
.
En décimal, cela donne 195
169
.
TROIS OCTETS : caractères "rares"
Les trois octets ont cette structure : 110x xxxx - 10xx xxxx - 10xx xxxx
.
Le premier octet commence par 111
suivi d'un bit 0
: cela veut dire qu'il faudra trois octets pour trouver la valeur UNICODE du caractère.
Les deux octets suivants commencent par 10
Il y a 16 x : on peut encoder 216 caractères supplémentaires (soit 65536).
Exemple :
Le "✐" est encodé par 1110 0010
1001 1100
1001 0000
.
En décimal, cela donne 226
156
144
.
QUATRE OCTETS : les caractères encore plus rares qu'on voudra y placer
Les quatre octets ont cette structure : 110x xxxx - 10xx xxxx - 10xx xxxx - 10xx xxxx
.
Le premier octet commence par 1111
suivi d'un bit 0
: cela veut dire qu'il faudra quatre octets pour trouver la valeur UNICODE du caractère.
Les trois octets suivants commencent par 10
Il y a 21 x : on peut encoder 221 caractères supplémentaires (soit plus de 2 millions).
Activité publiée le 09 02 2020
Dernière modification : 22 03 2021
Auteur : ows. h.