Nous allons voir aujourd'hui comment parvenir à encoder les textes et nous verrons qu'il est bien pratique d'utiliser pour cela une autre base que la base 2.
D'ailleurs, c'est même pire : il stocke des blocs de bits qu'on nomme octet pour le plus petit de ces blocs.
Alors, comment fait-il pour stocker des textes ?
Et oui, il stocke des octets !
Depuis les débuts de l'informatique, il y a eu des tables de correspondances entre les caractères courants de la langue anglo-saxonne et les valeurs que peut prendre un octet.
On aurait pu créer un encodage du type :
1 pour A,
2 pour B,
3 pour C ...
C'est oublier qu'avant d'ouvrir un texte l'ordinateur a besoin d'informations lorsqu'on transfère des fichiers sur le réseau
Où commence le fichier ? On peut utiliser le caractère STX pour Start of TeXt
Où s'arrête le fichier ? On peut utiliser le caractère ETX, End of TeXt
Où doit-il passer à la ligne ? On utilise le caractère Line Feed (nouvelle ligne) LF, '\n' en Python.
...
En plus des caractères dits imprimables, ASCII donne donc également un standard de valeurs normalisés aux caractères dits de contrôle.
1.1 Principe de la table ASCII
Avant ASCII, chaque matériel avait sa propre table d'encodage/décodage... Changer de support impliquait donc de changer les codes à inscrire !
La table ASCII est le standard incontournable des 128 premiers caractères.
Elle est publiée pour la première fois en 1963. La table ASCII attribue des valeurs aux lettres minuscules (a-z), majuscules (A-F), aux chiffres décimaux (0-9), aux caractères de ponctuation, à quelques symboles mathématiques ou non...
La taille choisie pour l'encodage des caractères était à l'époque 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.
Un petit bout de la table ASCII
Sous cette forme de tableau avec une ligne par caractère, cela va donner 128 lignes. Cette représentation prendrait beaucoup de place.
Caractère encodé
En binaire (7 bits)
En décimal
A
100 0001
65
B
100 0010
66
C
100 0011
67
On préfère représenter la correspondance Code/Caractère via un tableau à deux entrées.
1.2 Table ASCII en format décimal
Voilà la totalité de la table ASCII sous forme d'un tableau à double entrée. Les caractères de contrôle sont en fond jaune.
Par exemple, EOT code la fin d'une transmission (End of Transmission).
Beaucoup de ces caractères sont utilisés sur les protocoles de communications que nous verrons plus tard.
_0
_1
_2
_3
_4
_5
_6
_7
_8
_9
0_
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
1_
LF
VT
FF
CR
SO
SI
DLE
DC1
DC2
DC3
2_
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
3_
RS
US
!
"
#
$
%
&
'
4_
(
)
*
+
,
-
.
/
0
1
5_
2
3
4
5
6
7
8
9
:
;
6_
<
=
>
?
@
A
B
C
D
E
7_
F
G
H
I
J
K
L
M
N
O
8_
P
Q
R
S
T
U
V
W
X
Y
9_
Z
[
\
]
^
_
`
a
b
c
10_
d
e
f
g
h
i
j
k
l
m
11_
n
o
p
q
r
s
t
u
v
w
12_
x
y
z
{
|
}
~
DEL
_0
_1
_2
_3
_4
_5
_6
_7
_8
_9
On retrouve bien
le A avec un code 65 : 6 en ligne et 5 en colonne.
le a avec un code 97 : 9 en ligne et 7 en colonne.
Commençons par comprendre le message qu'a reçu notre grand chevalier :
01° Utiliser la table ASCII en décimal pour tenter de décoder le message reçu.
...CORRECTION...
Il suffit d'associer chaque valeur à la lettre que la valeur encode (s'il s'agit bien d'un texte ET que le texte a été encodé en respectant l'ASCII)
80 encode P
101 encode e
114 encode r
99 encode c
101 encode e
118 encode v
97 encode a
108 encode l
32 encode
63 encode ?
On constate quand même un problème non ?
Il reste deux cases vides dans le tableau... C'est bête. C'est simplement car le décimal n'est pas une base pratique pour représenter un octet : 256 possibilités.
Avec dix lignes sur dix colonnes, on aura juste 100 possibilités.
Or, il se trouve que 16 x 16 = 256.
Si on veut représenter sans perte de cases un tableau de ce type, le mieux est donc d'utiliser la base 16, l'hexadécimal.
Table ASCII en version hexadécimale
_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
C'est plus joli mais maintenant A vaut 41...
En réalité, non. Nous avons toujours la même valeur. Pourquoi ?
Avant d'en montrer toute l'utilité, voyons comme fonctionne l'hexadécimal.
2.1 Cases
Voyons comment fonctionne le décodage d'un nombre en base 16 ainsi que l'addition.
Que peut-on mettre dans les cases en hexadécimal ?
Des chiffres.
Combien et lesquels ?
Base 16 donc 16 CHIFFRES : 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - A - B - C - D - E - F .
Pourquoi avoir pris des lettres plutôt que d'inventer de nouveaux symboles ? Parce que c'est plus facile ! En plus, les tables ne comportant que 128 symboles initialement, c'était plus rentable de recycler plutôt que d'en inventer de nouveaux. Il n'y avait déjà plus de place.
De 0 à 9, ce ne change pas :
N = 010= 016
N = 110= 116
N = 210= 216
...
N = 910= 916
Mais ensuite
N = 1010= A16
N = 1110= B16
N = 1210= C16
N = 1310= D16
N = 1410= E16
N = 1510= F16
La case de poids faible ( 1 ) est toujours située à droite.
Poids de case exprimé en puissance de 16
On peut écrire facilement le poids des cases en utilisant les puissances de 16 :
La case code
4096
256
16
1
qu'on peut écrire sous la forme
163
162
161
160
Exemple
Si j'écris M= 342916, je fais ceci en réalité dans ma tête :
Nombre M =
3
4
2
9
La case code
4096
256
16
1
On obtient donc
4096*3
256*4
16*2
1*9
D'ou la valeur de M en base 10 : M = 4096*3 + 256*4 + 16*2 + 9 = 13353 .
On peut donc écrire N = 342916 = 1335310.
L'exemple ne comporte aucun chiffre A à F volontairement. Difficile de savoir que 3429 est un nombre exprimé en hexadécimale si on ne l'indique pas par l'indice 16.
02° Montrer qu'on a bien N = 4116 = 6510. Il s'agit des deux valeurs rencontrées pour A en ASCII.
...CORRECTION...
Il suffit de calculer la valeur en base 10 avec 4 dans la case de droite et 1 dans la case de gauche..
On obtient N = 4 * 16 + 1 = 65.
03° Montrer que N = FF16 = 25510. Il s'agit de la valeur maximale pour un octet.
...CORRECTION...
Il suffit de calculer la valeur en base 10 avec F dans la case de droite et F dans la case de gauche.
Le chiffre F en base 16 correspond au nombre 15 en base 10.
On obtient N = 15 * 16 + 15 * 1 = 255.
04° Montrer que N = FE16 = 25410. Il s'agit de la valeur maximale pour un octet.
...CORRECTION...
Il suffit de calculer la valeur en base 10 avec F dans la case de droite et E dans la case de gauche.
Le chiffre E en base 16 correspond au nombre 14 en base 10.
On obtient N = 15 * 16 + 14 * 1 = 254.
2.2 Addition
Alors ça fonctionne comment l'addition ? Pourquoi F+1 donne 10 ? On se le demande non ?
Jusqu'à F, il n'y a pas de difficulté, il suffit de suivre la liste des CHIFFRES disponibles.
Base 16 donc 16 CHIFFRES : 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - A - B - C - D - E - F .
Méthode à utiliser pour incrémenter (rajouter 1)
Tenter de rajouter 1 dans la case de l'unité (la case de poids faible, celle de droite). Pour cela, il suffit de placer le prochain chiffre dans la liste 0 ⇨ 1 ⇨ 2 ⇨ 3 ⇨ 4 ⇨ 5 ⇨ 6 ⇨ 7 ⇨ 8 ⇨ 9 ⇨ A ⇨ B ⇨ C ⇨ D ⇨ E ⇨ F
Si on est déja au dernier chiffre ( F ), on revient au premier chiffre ( 0 ) dans cette case ET on rajoute un dans la case juste à gauche. On fait une retenue.
Exemple 1 :
Si on rajoute 1 à
9
on obtient
A
...EXPLICATION...
On peut augmenter le chiffre de l'unité 9 en le faisant juste passer au chiffre suivant : A .
Exemple 2 :
Si on rajoute 1 à
E
on obtient
F
...EXPLICATION...
On peut augmenter le chiffre de l'unité E en le faisant juste passer au chiffre suivant : F .
Exemple 3 : cette fois, on va devoir rajouter une case à droite (elle contient 0 initialement puisqu'elle n'apparaît pas)
Si on rajoute 1 à
F
on obtient
1
0
...EXPLICATION...
On ne peut augmenter le chiffre de l'unité qui est déjà à F .
On la passe donc à 0 ET on incrémente la case juste à gauche.
La case de gauche était initialement à 0 : elle passe donc à 1 .
Exemple 4 :
Si on rajoute 1 à
1
3
on obtient
1
4
...EXPLICATION...
On peut augmenter le chiffre de l'unité 3 en le faisant juste passer au chiffre suivant : 4 .
Exemple 5 :
Si on rajoute 1 à
F
3
on obtient
F
4
...EXPLICATION...
On peut augmenter le chiffre de l'unité 3 en le faisant juste passer au chiffre suivant : 4 .
Exemple 6 :
Si on rajoute 1 à
3
F
F
on obtient
4
0
0
...EXPLICATION...
On ne peut augmenter le chiffre qui est déjà à F .
On la passe donc à 0 ET on incrémente la case juste à gauche.
La case juste à gauche était initialement à F : elle passe donc à 0 également et on va devoir augmenter de 1 la case suivante, la case la plus à gauche.
Le chiffre des centaines 3 passe donc à 4 .
2.3 Nombres de cas dénombrables
Si on ne possède qu'une case ? à remplir, on peut donc définir 16 valeurs de 0 à 15 10 ( soit F 16).
Comme le premier cas est numéroté 0, on a bien 15+1 = 16 valeurs possibles.
Si on dispose de 2 cases ?? à remplir, on peut définir des valeurs de 00 à FF .
Comme le premier cas est numéroté 0, on a bien 255+1 = 256 valeurs possibles.
On voit bien qu'il y a une généralisation à trouver. Laquelle ?
Nombre de cas dénombrables en base 16
En hexadécimal, si on dispose de X cases pouvant accueillir un des 16 chiffres de la base 16, le nombre de valeurs possibles est 16X10.
Attention : dans la mesure où le premier cas est 0, la valeur maximale est donc 16X - 110
Exemple : si on dispose de 4 cases
Le nombre de possibilité est 164 = 65 536
On peut alors stocker des valeurs partant de 0 jusqu'à 65535.
2.4 Bilan sur la base 16 (hexadécimal)
Résumé hexadécimal
Que peut-on mettre dans les cases d'un nombre en base 16 ?
Des chiffres. Combien et lesquels ?
Base 10 donc 10 CHIFFRES : 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - A - B - C - D - E - F .
On peut facilement trouver le poids des cases en utilisant les puissances de 16 :
La case code
4096
256
16
1
qu'on peut écrire sous la forme
163
162
161
160
Méthode à utiliser pour incrémenter (rajouter 1)
Tenter de rajouter 1 dans la case de l'unité (la case de poids faible, celle de droite). Pour cela, il suffit de placer le prochain chiffre dans la liste 0 ⇨ 1 ⇨ 2 ⇨ 3 ⇨ 4 ⇨ 5 ⇨ 6 ⇨ 7 ⇨ 8 ⇨ 9 ⇨ A ⇨ B ⇨ C ⇨ D ⇨ E ⇨ F
Si on est déja au dernier chiffre ( F ), on revient au premier chiffre ( 0 ) dans cette case ET on rajoute un dans la case juste à gauche.
Nombre de valeurs disponibles en base 16
En hexadécimal, si on dispose de X cases pouvant accueillir un des 10 chiffres de la base 16, le nombre de valeurs possibles est 16X.
Attention : dans la mesure où le premier cas est 0, la valeur maximale est donc 16X - 1
On peut assez facilement les transformer en base 16 :
5 0 6 5 7 2 6 3 6 5 7 6 6 1 6 C 2 0 3 F
07° Vérifier que les 4 premiers octets soient bien 50 65 72 63 en hexadécimal.
...CORRECTION...
Pour le premier octet, on a les quartets suivants
0101 , ce qui donne 0+4+0+1 = 5.
0000 , ce qui donne 0+0+0+0 = 0.
08° Vérifier le début du message en utilisant la table hexa ci-dessous.
5 0 6 5 7 2 6 3 6 5 7 6 6 4 6 C 2 0 3 F
Table ASCII en version hexadécimale
_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
09° Vérifier que 5016 correspond bien à 8010.
...CORRECTION...
Il suffit de gérer les cases avec les poids de 16 et 1.
N = 5 * 16 + 1 * 0 = 80
Il s'agit encore du P si on regarde la table en décimal. Ouf.
La première utilisation massive de l'hexadécimal en informatique date de 1956 avec l'ordinateur Bendix-G15. 450kg, plus d'un m3, pour un prix qui correspondrait actuellement à environ 500 000 $ !
Le concepteur en chef du G15 est l’informaticien et mathématicien Harry Huskey. Celui-ci avait travaillé auparavant avec le celèbre Alan Turing ainsi que sur le premier ordinateur entièrement électronique, le non moins célèbre ENIAC. Celui-ci, financé pendant la Seconde Guerre Mondiale, en 1943 prend encore plus de place :
Préfixes permettant de préciser la base des nombres
Pour fournir un nombre en binaire, il fallait le précéder de 0b.
Pour l'hexadécimal, c'est 0x.
On utilise cette notation (par exemple 0xFF) car c'est plus facile que d'indiquer (et encore plus qu'afficher) les indices (par exemple FF16).
11° Utiliser les instructions suivantes dans la console : Python sait calculer et convertir les nombres fournis en base 16 mais affiche par défaut le résultat en base 10.
Comme avec la fonction bin, on peut supprimer les deux premiers caractères de la chaîne de caractères en utilisant [2:]. Cela veut dire : ne fournir que les caractères d'index 2 et plus. Il va donc supprimer de la réponse les caractères d'index 0 et 1.
Pour finir cette activité, voici une procédure qui permet d'afficher les codes ASCII d'une chaîne de caractères (qui ne doit donc comporter que des caractères issus de la table ASCII).
defvoir_encodage(texte,encodage_voulu,base_voulue):"""Procédure qui affiche les octets encodant le texte ::param texte (str) :: le texte à analyser ::param encodage_voulu (str) :: un nom valide d'encodage ::param base_voulue (int) :: la base voulue en réponse parmi 2-10 ou 16 ..warning :: Les caractères de texte doivent être encodables avec l'encodage ..note :: toutes bases non voulues sera traitées comme 10. """encodage=texte.encode(encodage_voulu)foroctetinencodage:ifbase_voulue==2:valeur=bin(octet)[2:].rjust(8,'0')elifbase_voulue==16:valeur=hex(octet)[2:]else:valeur=str(octet).rjust(3,'0')print(valeur,end=" - ")voir_encodage("Perceval ?","ascii",16)
12° Utiliser le programme pour visualiser les différentes valeurs des mêmes octets dans les 3 bases.
13° Tenter de faire de même avec un texte comportant des caractères non ASCII, comme par exemple "Perceval, ça va ?".
C'est problématique comme le caractère ç n'existe pas dans cette table, pas moyen d'obtenir une réponse.
14° Remplacer l'encodage "ascii" par "iso8859_15" par exemple. Demander à voir le résultat en base 10. Il s'agit de la table des caractères des pays d'Europe de l'Ouest, sous le format 1 caractère encodé par un octet uniquement.
Le caractère en gras est le ç, encodé par un nombre supérieur à 127 car on utilise cette fois bien les 8 bits de l'octet.
Il n'y a donc que 256 possibilités de caractères différents avec les encodages sur un octet.
15° Remplacer l'encodage "iso8859_15" par "utf-8" . Demander à voir le résultat en base 10. Par comparaison, trouver les octets qui permettent d'encoder le ç.