En informatique, un même nombre peut porter plusieurs déguisements.
La quantité :
255
peut par exemple s’écrire :
Décimal 255
Binaire 11111111
Octal 377
Hexadécimal FF
Quatre écritures différentes, mais exactement la même valeur.
À côté de ces systèmes de numération, on rencontre aussi des encodages de caractères comme ASCII et Unicode, qui répondent à une autre question :
comment associer des nombres à des caractères comme A, @, é ou € ?
Comprendre cette distinction évite déjà une grande partie des confusions entre binaire, hexadécimal, texte et données brutes.
Avant tout : base numérique et encodage ne sont pas la même chose
Le :
binaire
octal
décimal
hexadécimal
désigne des systèmes de numération.
Ils permettent d’écrire des nombres.
ASCII, Unicode ou UTF-8 sont liés à la représentation de caractères.
Par exemple, le nombre :
65
peut s’écrire :
Décimal 65
Binaire 01000001
Octal 101
Hexadécimal 41
ASCII décide ensuite que la valeur :
65
correspond au caractère :
A
Autrement dit :
01000001
0x41
65
101 en octal
ne sont pas quatre caractères différents.
Ce sont quatre manières d’écrire la même valeur numérique.
Le principe d’une base
Notre système habituel est la base 10.
Il utilise dix chiffres :
0 1 2 3 4 5 6 7 8 9
Chaque position représente une puissance de 10.
Par exemple :
325
= 3 × 10²
+ 2 × 10¹
+ 5 × 10⁰
= 300 + 20 + 5
Les autres bases suivent exactement le même principe.
| Base | Nom | Symboles utilisés |
|---|---|---|
| 2 | Binaire | 0, 1 |
| 8 | Octal | 0 à 7 |
| 10 | Décimal | 0 à 9 |
| 16 | Hexadécimal | 0 à 9, A à F |
Le binaire : deux symboles suffisent
Le système binaire utilise seulement :
0
1
Chaque position correspond à une puissance de :
2
Par exemple :
1101₂
= 1 × 2³
+ 1 × 2²
+ 0 × 2¹
+ 1 × 2⁰
= 8 + 4 + 0 + 1
= 13₁₀
Pourquoi l’informatique utilise-t-elle le binaire ?
Les systèmes numériques sont construits autour d’états physiques que l’on peut distinguer de manière fiable.
On peut abstraire ces états sous la forme :
0
1
Ils servent ensuite à représenter :
- des nombres ;
- des instructions ;
- des adresses mémoire ;
- des caractères ;
- des images ;
- du son ;
- des paquets réseau ;
- des états logiques.
Dire que « le processeur parle binaire » est donc une simplification utile.
Plus précisément, les circuits numériques manipulent des états physiques interprétés selon une logique binaire.
Le bit
Un bit est un chiffre binaire :
binary digit
→ bit
Il peut prendre deux valeurs :
0
ou
1
Combien de valeurs peut-on représenter ?
Avec :
n bits
on peut représenter :
2ⁿ combinaisons
Exemples :
| Nombre de bits | Combinaisons possibles | Plage non signée |
|---|---|---|
| 1 | 2 | 0 à 1 |
| 2 | 4 | 0 à 3 |
| 4 | 16 | 0 à 15 |
| 8 | 256 | 0 à 255 |
| 16 | 65 536 | 0 à 65 535 |
| 32 | 4 294 967 296 | 0 à 4 294 967 295 |
L’octet
Un octet contient exactement :
8 bits
Il possède donc :
2⁸ = 256
configurations possibles.
Pour un entier non signé :
00000000 = 0
00000001 = 1
00000010 = 2
...
11111111 = 255
Pourquoi 256 valeurs mais seulement jusqu’à 255 ?
Parce que :
0
est lui aussi une valeur.
La plage :
0 à 255
contient bien :
256 nombres
Les poids des huit bits
Un octet peut être représenté ainsi :
Bit : 7 6 5 4 3 2 1 0
Valeur : 128 64 32 16 8 4 2 1
Pour :
01010101
on additionne :
64 + 16 + 4 + 1
=
85
Donc :
01010101₂ = 85₁₀
Conversion binaire vers décimal
Prenons :
10110110
On applique les poids :
1 × 128 = 128
0 × 64 = 0
1 × 32 = 32
1 × 16 = 16
0 × 8 = 0
1 × 4 = 4
1 × 2 = 2
0 × 1 = 0
Total = 182
Donc :
10110110₂ = 182₁₀
Conversion décimal vers binaire
Pour convertir :
45
on peut chercher les puissances de 2 nécessaires :
45 = 32 + 8 + 4 + 1
Donc :
32 16 8 4 2 1
1 0 1 1 0 1
et :
45₁₀ = 101101₂
Le contexte change parfois la signification des mêmes bits
Considérons :
11111111
Interprété comme entier non signé sur 8 bits :
255
Mais dans une représentation signée moderne en complément à deux sur 8 bits, le même motif peut représenter :
-1
Les bits seuls ne suffisent donc pas toujours.
Il faut connaître :
- le type de donnée ;
- la taille ;
- le caractère signé ou non signé ;
- le format utilisé.
Une suite de bits n’a pas de signification universelle. Sa signification dépend de la manière dont on décide de l’interpréter.
L’hexadécimal : quatre bits par chiffre
L’hexadécimal utilise seize symboles :
0 1 2 3 4 5 6 7 8 9 A B C D E F
Les lettres correspondent à :
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15
Comme :
16 = 2⁴
un chiffre hexadécimal représente exactement :
4 bits
Table de correspondance
| Décimal | Binaire | Hexadécimal |
|---|---|---|
| 0 | 0000 |
0 |
| 1 | 0001 |
1 |
| 2 | 0010 |
2 |
| 3 | 0011 |
3 |
| 4 | 0100 |
4 |
| 5 | 0101 |
5 |
| 6 | 0110 |
6 |
| 7 | 0111 |
7 |
| 8 | 1000 |
8 |
| 9 | 1001 |
9 |
| 10 | 1010 |
A |
| 11 | 1011 |
B |
| 12 | 1100 |
C |
| 13 | 1101 |
D |
| 14 | 1110 |
E |
| 15 | 1111 |
F |
Pourquoi l’hexadécimal est-il si pratique ?
Prenons l’octet :
11110110
On le découpe par groupes de quatre bits :
1111 0110
Puis :
1111 = F
0110 = 6
Donc :
11110110₂ = F6₁₆
Huit caractères binaires deviennent seulement :
2 caractères hexadécimaux
Voilà pourquoi l’hexadécimal est omniprésent dès que des humains doivent examiner des données binaires sans perdre immédiatement toute volonté de vivre.
Un octet correspond à deux chiffres hexadécimaux
Comme :
8 bits
=
2 × 4 bits
on obtient :
00000000 = 00
11111111 = FF
Donc :
0x00 = 0
0x7F = 127
0x80 = 128
0xFF = 255
Que signifie le préfixe 0x ?
Dans de nombreux langages et outils :
0xFF
indique que :
FF
doit être interprété en base 16.
On rencontre par exemple :
0x10 = 16
0x20 = 32
0x64 = 100
0xFF = 255
Mais le préfixe est une convention de syntaxe utilisée par différents langages et outils, pas une partie intrinsèque du nombre.
Hexadécimal et adresses mémoire
Les adresses mémoire sont très souvent présentées en hexadécimal :
0x00007FFDEADB1234
Pourquoi ?
Parce que chaque chiffre correspond directement à quatre bits, ce qui facilite énormément la lecture des champs binaires.
Hexadécimal et dumps mémoire
Un dump peut ressembler à :
48 65 6C 6C 6F 20 57 6F 72 6C 64
Ces octets peuvent représenter, selon l’encodage :
Hello World
La vue hexadécimale permet d’observer précisément les octets présents sans devoir afficher :
010010000110010101101100...
qui reste une excellente façon de punir un stagiaire n’ayant rien fait de particulier.
0xDEADBEEF
La valeur :
0xDEADBEEF
est devenue un classique de l’informatique.
Elle appartient à une tradition de valeurs hexadécimales facilement reconnaissables utilisées comme :
- marqueurs ;
- valeurs de test ;
- motifs de débogage ;
- signatures internes.
On rencontre également des créations comme :
CAFEBABE
DEADC0DE
BAADF00D
L’hexadécimal est l’une des rares disciplines où un développeur peut écrire « dead beef » dans un programme et prétendre légitimement travailler.
Hexadécimal et couleurs Web
En CSS, une couleur peut être écrite :
#RRGGBB
Chaque composante utilise un octet :
RR = rouge
GG = vert
BB = bleu
Chaque composante varie entre :
00
et
FF
soit :
0 à 255
Quelques exemples
#000000 = noir
#FFFFFF = blanc
#FF0000 = rouge
#00FF00 = vert
#0000FF = bleu
#FFFF00 = jaune
#00FFFF = cyan
#FF00FF = magenta
#FFFFFF et 0xFFFFFF ne sont pas exactement la même notation
Numériquement :
FFFFFF₁₆
=
16 777 215₁₀
Mais dans CSS, la syntaxe de couleur est :
#FFFFFF
et non :
0xFFFFFF
Le nombre est identique, le contexte syntaxique ne l’est pas.
L’octal : la base 8
L’octal utilise huit chiffres :
0 1 2 3 4 5 6 7
Comme :
8 = 2³
un chiffre octal correspond exactement à :
3 bits
Table binaire / octal
| Binaire | Octal |
|---|---|
000 |
0 |
001 |
1 |
010 |
2 |
011 |
3 |
100 |
4 |
101 |
5 |
110 |
6 |
111 |
7 |
Convertir facilement du binaire en octal
Prenons :
111101101
On découpe par groupes de trois :
111 101 101
Ce qui donne :
7 5 5
Donc :
111101101₂ = 755₈
Et voilà pourquoi l’octal est particulièrement naturel pour les permissions Unix.
Permissions Unix : pourquoi 755 ?
Les trois permissions classiques sont :
r = read
w = write
x = execute
Chaque droit correspond à un bit :
r = 100₂ = 4₈
w = 010₂ = 2₈
x = 001₂ = 1₈
On peut donc additionner les valeurs.
| Octal | Binaire | Permissions |
|---|---|---|
| 0 | 000 |
--- |
| 1 | 001 |
--x |
| 2 | 010 |
-w- |
| 3 | 011 |
-wx |
| 4 | 100 |
r-- |
| 5 | 101 |
r-x |
| 6 | 110 |
rw- |
| 7 | 111 |
rwx |
Comprendre chmod 755
La commande :
chmod 755 script.sh
correspond à :
7 = rwx
5 = r-x
5 = r-x
Les trois chiffres représentent :
propriétaire
groupe
autres
Donc :
rwxr-xr-x
chmod 644
6 = rw-
4 = r--
4 = r--
Donc :
rw-r--r--
C’est un mode classique pour de nombreux fichiers ordinaires.
chmod 777
7 = rwx
7 = rwx
7 = rwx
Donc :
rwxrwxrwx
Tous les utilisateurs obtiennent les permissions classiques de lecture, écriture et exécution.
Cela ne signifie cependant pas :
« Tous les droits Unix imaginables. »
Il existe aussi des bits spéciaux :
- setuid ;
- setgid ;
- sticky bit.
Le quatrième chiffre des permissions
On peut rencontrer :
4755
2755
1777
Le premier chiffre représente les bits spéciaux :
4 = setuid
2 = setgid
1 = sticky
Par exemple :
chmod 1777 /repertoire
ajoute le sticky bit aux permissions classiques :
777
Faut-il écrire 0755 ou 755 ?
Avec :
chmod
un mode numérique est interprété en octal.
Ainsi :
chmod 755 fichier
est suffisant.
On voit néanmoins souvent :
0755
dans les langages de programmation ou les documentations pour rendre explicite la nature octale de la valeur.
Le piège du zéro initial
Dans certains contextes de programmation, un entier commençant par :
0
est interprété en octal.
Par exemple, dans l’arithmétique Bash :
010
signifie :
8 en décimal
et :
08
pose problème puisque :
8
n’est pas un chiffre valide en base 8.
Le zéro initial n’est donc pas toujours une décoration innocente.
Les préfixes courants
De nombreux langages utilisent des notations ressemblant à :
| Base | Notation courante |
|---|---|
| Binaire | 0b1010 |
| Octal | 0o755 ou parfois 0755 |
| Décimal | 123 |
| Hexadécimal | 0xFF |
La syntaxe exacte dépend toutefois du langage.
Par exemple :
Python
C
JavaScript
Bash
Rust
ne possèdent pas nécessairement exactement les mêmes règles historiques.
ASCII : des nombres pour représenter des caractères
ASCII signifie :
American Standard Code
for Information Interchange
Contrairement au binaire ou à l’hexadécimal, ASCII n’est pas une base numérique.
C’est un :
jeu de caractères codés
Il associe des valeurs numériques à des caractères et fonctions de contrôle.
ASCII utilise 7 bits
ASCII définit les valeurs :
0 à 127
soit :
128 positions
On peut les représenter en binaire sur :
7 bits
ou dans un octet dont le bit supérieur vaut zéro.
Quelques codes ASCII essentiels
| Décimal | Hexa | Nom / caractère |
|---|---|---|
| 0 | 00 |
NUL |
| 9 | 09 |
HT, tabulation horizontale |
| 10 | 0A |
LF, Line Feed |
| 13 | 0D |
CR, Carriage Return |
| 32 | 20 |
Espace |
| 48 | 30 |
0 |
| 57 | 39 |
9 |
| 64 | 40 |
@ |
| 65 | 41 |
A |
| 90 | 5A |
Z |
| 92 | 5C |
Backslash |
| 97 | 61 |
a |
| 122 | 7A |
z |
| 127 | 7F |
DEL |
ASCII 65 = A
Le caractère :
A
possède la valeur ASCII :
65 décimal
41 hexadécimal
101 octal
1000001 binaire
Encore une fois :
A
est le caractère.
Les autres valeurs représentent son code numérique sous plusieurs bases.
Les lettres sont organisées intelligemment
Les lettres majuscules sont contiguës :
A = 65
B = 66
C = 67
...
Z = 90
Les minuscules également :
a = 97
b = 98
c = 99
...
z = 122
La différence entre une lettre ASCII majuscule et sa minuscule correspond à :
32 décimal
=
0x20
Cette organisation explique certaines vieilles astuces de programmation bas niveau.
Les chiffres ASCII ne sont pas leurs valeurs numériques
Le caractère :
'0'
ne possède pas le code ASCII :
0
mais :
48
=
0x30
Ainsi :
'0' → 48
'1' → 49
'2' → 50
...
'9' → 57
C’est fondamental en programmation.
La chaîne :
"123"
contient des caractères dont les codes sont :
0x31 0x32 0x33
Elle n’est pas automatiquement stockée comme l’entier binaire :
123
NUL, NULL et ‘\0’ : trois écritures qu’il ne faut pas mélanger
Le caractère ASCII numéro :
0
porte le nom :
NUL
Dans les langages C et C++, le caractère nul peut notamment être écrit :
'\0'
Les chaînes C conventionnelles se terminent par cet octet nul.
Par exemple, la chaîne :
"chat"
est représentée conceptuellement par :
c h a t NUL
63 68 61 74 00
en hexadécimal
NULL est autre chose
Dans le contexte du C :
NULL
est généralement utilisé pour représenter une constante de pointeur nul.
Il ne faut donc pas écrire :
ASCII 0 = NULL
mais :
ASCII 0 = NUL
NUL ne signifie pas « fin de chaîne » dans tous les systèmes
ASCII donne au code 0 le nom :
NUL
Mais son utilisation comme terminateur de chaîne relève de conventions logicielles, notamment celles du langage C.
Un fichier ou protocole peut parfaitement contenir des octets :
00
pour une autre raison.
Tabulation, LF et CR
Les codes de contrôle ASCII apparaissent encore partout.
Tabulation
ASCII 9
hex 09
souvent écrit \t
Line Feed
ASCII 10
hex 0A
souvent écrit \n
Carriage Return
ASCII 13
hex 0D
souvent écrit \r
Fin de ligne Unix/Linux
Les fichiers texte Unix et Linux utilisent traditionnellement :
LF
soit :
0A
Fin de ligne Windows
Les fichiers texte Windows conventionnels utilisent historiquement :
CR LF
soit :
0D 0A
On résume souvent :
Linux \n
Windows \r\n
Cela reste une convention de format de texte, pas une loi imposée à chaque fichier existant sur ces systèmes.
Pourquoi les scripts affichent parfois ^M ?
Lorsqu’un fichier utilisant :
CRLF
est interprété dans un environnement qui s’attend uniquement à :
LF
le caractère CR supplémentaire peut devenir visible sous une forme ressemblant à :
^M
Un seul octet peut ainsi suffire à provoquer une quantité de mauvaise humeur largement disproportionnée à sa taille.
ASCII s’arrête à 127
C’est une correction particulièrement importante :
ASCII
=
0 à 127
Donc :
255
n’est pas un caractère ASCII.
Et « ASCII étendu » ?
L’expression :
ASCII étendu
est ambiguë.
Plusieurs encodages 8 bits historiques ont utilisé les valeurs :
128 à 255
mais pas toujours pour les mêmes caractères.
On peut notamment rencontrer :
- ISO-8859-1 ;
- Windows-1252 ;
- différentes code pages DOS ;
- d’autres encodages nationaux.
Il n’existe donc pas un unique standard universel :
ASCII 8 bits
0 à 255
Pourquoi « ÿ au lieu de é » arrive-t-il ?
Parce qu’une suite d’octets n’a de sens textuel que lorsqu’on connaît :
son encodage
Le même octet peut être interprété différemment selon :
- la code page ;
- l’encodage ;
- le programme ;
- les paramètres régionaux.
Les problèmes appelés :
mojibake
apparaissent justement lorsqu’un texte est décodé avec le mauvais encodage.
ASCII ne suffit pas au monde moderne
ASCII contient essentiellement :
- alphabet latin anglais ;
- chiffres ;
- ponctuation ;
- caractères de contrôle.
Il ne sait pas représenter directement :
é
à
ç
€
漢
א
ش
😀
Pour cela, le monde moderne utilise principalement :
Unicode
Unicode : attribuer des points de code
Unicode attribue un :
code point
point de code
aux caractères.
La notation utilise :
U+...
Par exemple :
A = U+0041
é = U+00E9
€ = U+20AC
😀 = U+1F600
Unicode n’est pas UTF-8
C’est une distinction essentielle.
Unicode définit notamment :
quels caractères existent
et
quel point de code leur correspond
UTF-8 définit :
comment ces points de code
sont représentés sous forme d'octets
UTF-8
UTF-8 utilise des unités de :
8 bits
et encode les points de code sur une longueur variable.
Selon la valeur :
1 à 4 octets
sont nécessaires.
ASCII est directement préservé dans UTF-8
Les caractères Unicode :
U+0000 à U+007F
sont représentés en UTF-8 par exactement les mêmes valeurs :
00 à 7F
Par exemple :
A
ASCII :
41 hex
UTF-8 :
41 hex
C’est l’une des propriétés ayant facilité l’adoption de UTF-8 dans les systèmes historiquement fondés sur ASCII.
Le caractère é en UTF-8
Le caractère :
é
correspond au point de code :
U+00E9
En UTF-8, il est encodé avec deux octets :
C3 A9
Donc :
é
≠ un octet E9 en UTF-8
Cette dernière représentation peut exister dans certains anciens encodages 8 bits, mais ce n’est pas UTF-8.
Caractère, point de code et octet ne sont donc pas synonymes
Il faut distinguer :
caractère
↓
point de code Unicode
↓
encodage
↓
séquence d'octets
Pour ASCII simple, ces concepts semblent presque identiques parce que :
A
→ U+0041
→ 0x41
Mais dès qu’on sort d’ASCII, cette illusion disparaît.
Pourquoi 255 apparaît partout en réseau ?
Dans IPv4, une adresse comporte :
32 bits
présentés traditionnellement sous forme de quatre octets décimaux :
192.168.1.42
Chaque octet peut contenir :
0 à 255
car :
255
=
11111111₂
=
FF₁₆
Le masque 255.255.255.0
Le masque :
255.255.255.0
correspond en binaire à :
11111111.11111111.11111111.00000000
Il possède :
24 bits à 1
et s’écrit donc en CIDR :
/24
255 n’a ici absolument rien à voir avec ASCII
Le :
255
du masque est simplement la représentation décimale de :
11111111
Il n’existe aucune notion de :
caractère ASCII numéro 255
dans ce calcul.
Binaire et masques de bits
Le binaire est particulièrement utile pour les opérations :
AND
OR
XOR
NOT
utilisées pour manipuler des bits individuels.
AND
L’opération AND donne 1 uniquement si les deux bits valent 1 :
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
Par exemple :
11010110
AND
11110000
--------
11010000
Cette technique permet de masquer certains bits.
Pourquoi les masques IP utilisent-ils AND ?
Une adresse IPv4 :
192.168.1.42
avec le masque :
255.255.255.0
peut être combinée par AND pour obtenir l’adresse réseau :
192.168.1.0
Le système de numération devient alors directement utile au diagnostic réseau.
Hexadécimal et adresses IPv6
IPv6 utilise :
128 bits
Les afficher en binaire serait possible :
0010000000000001...
mais humainement peu raisonnable.
IPv6 utilise donc naturellement l’hexadécimal :
2001:db8:1234:5678::1
Chaque groupe classique de quatre chiffres hexadécimaux représente :
16 bits
Hexadécimal et adresses MAC
Une adresse MAC est également couramment écrite en hexadécimal :
00:1A:2B:3C:4D:5E
Chaque paire hexadécimale représente :
1 octet
Donc :
6 groupes × 8 bits
=
48 bits
pour une adresse MAC traditionnelle de 48 bits.
Pourquoi apprendre ces conversions quand les ordinateurs savent les faire ?
Parce que comprendre les représentations permet de lire immédiatement des informations qui seraient autrement opaques.
Réseau
255.255.255.0
/24
FF:FF:FF:FF:FF:FF
2001:db8::1
Permissions Linux
644
755
750
600
1777
Débogage
0xC0000005
0xDEADBEEF
0x7F
FF 00 12 A4
Programmation
flags
bitmasks
registres
adresses
protocoles
Web
#FFFFFF
#637558
#C86643
Encodage
ASCII
UTF-8
Unicode
code points
Encodage, chiffrement et hachage : trois choses différentes
Un point important pour la sécurité :
hexadécimal
Base64
UTF-8
ne constituent pas du chiffrement.
Ils servent à :
représenter
ou
encoder
des données.
Une chaîne :
48656C6C6F
peut sembler mystérieuse mais correspond simplement, en ASCII/UTF-8, aux octets de :
Hello
Il n’y a aucune confidentialité.
La transformer depuis l’hexadécimal demande des connaissances cryptographiques comparables à celles nécessaires pour ouvrir une enveloppe déjà décachetée.
Erreur classique : croire que le binaire est un autre nombre
Ces valeurs sont identiques :
42₁₀
101010₂
52₈
2A₁₆
Ce n’est que leur représentation qui change.
Erreur classique : croire que l’hexadécimal va jusqu’à F puis recommence à 0
Après :
F
vient :
10
en hexadécimal.
Mais :
10₁₆ = 16₁₀
De même :
FF₁₆ = 255₁₀
100₁₆ = 256₁₀
Erreur classique : confondre chiffre et nombre
En hexadécimal :
F
est un chiffre représentant la valeur :
15
Alors que :
FF
est un nombre composé de deux chiffres hexadécimaux.
Erreur classique : dire qu’ASCII possède 256 caractères
Non :
ASCII = 128 positions
0 à 127
Les systèmes 8 bits historiques utilisant :
128 à 255
sont d’autres encodages ou extensions.
Erreur classique : appeler NUL « NULL »
ASCII :
NUL
code 0
C/C++ :
'\0'
caractère nul
Pointeur nul C :
NULL
Les trois notions sont liées par quelques zéros, mais elles ne sont pas interchangeables.
Erreur classique : croire que 255 est un caractère ASCII
Dans :
255.255.255.0
les valeurs représentent des octets d’un masque IPv4 sous forme décimale.
ASCII n’intervient pas dans la valeur du masque.
Erreur classique : considérer 0755 comme universel
La manière d’écrire un nombre octal dépend du contexte.
Avec GNU chmod :
chmod 755 fichier
est suffisant.
Dans l’arithmétique Bash :
0755
est interprété comme une constante octale.
Dans d’autres langages modernes, on pourra rencontrer :
0o755
Erreur classique : croire qu’un caractère correspond toujours à un octet
En ASCII :
A
→ 1 octet en UTF-8
Mais :
é
utilise :
2 octets en UTF-8
et certains caractères Unicode nécessitent :
4 octets
en UTF-8.
Donc :
1 caractère
≠
toujours 1 octet
Erreur classique : confondre point de code et encodage
Le caractère :
é
possède le point de code :
U+00E9
mais son encodage UTF-8 est :
C3 A9
Ce sont deux niveaux différents de représentation.
Tableau de conversion pratique
| Décimal | Binaire | Octal | Hexadécimal |
|---|---|---|---|
| 0 | 00000000 |
000 |
00 |
| 1 | 00000001 |
001 |
01 |
| 7 | 00000111 |
007 |
07 |
| 8 | 00001000 |
010 |
08 |
| 10 | 00001010 |
012 |
0A |
| 15 | 00001111 |
017 |
0F |
| 16 | 00010000 |
020 |
10 |
| 31 | 00011111 |
037 |
1F |
| 32 | 00100000 |
040 |
20 |
| 64 | 01000000 |
100 |
40 |
| 65 | 01000001 |
101 |
41 |
| 127 | 01111111 |
177 |
7F |
| 128 | 10000000 |
200 |
80 |
| 255 | 11111111 |
377 |
FF |
Quelques puissances de 2 à connaître
| Puissance | Valeur |
|---|---|
2⁰ |
1 |
2¹ |
2 |
2² |
4 |
2³ |
8 |
2⁴ |
16 |
2⁵ |
32 |
2⁶ |
64 |
2⁷ |
128 |
2⁸ |
256 |
2¹⁰ |
1 024 |
2¹⁶ |
65 536 |
2³² |
4 294 967 296 |
Les raccourcis les plus utiles
Pour passer du binaire à l’hexadécimal :
groupes de 4 bits
Pour passer du binaire à l’octal :
groupes de 3 bits
Pour un octet :
8 bits
=
2 chiffres hexadécimaux
Pour un entier non signé sur 8 bits :
minimum = 0
maximum = 255
Pour un entier non signé sur n bits :
maximum = 2ⁿ - 1
Exemple complet : la valeur 192
En décimal :
192
En binaire :
11000000
car :
128 + 64 = 192
En hexadécimal :
C0
car :
1100 = C
0000 = 0
En octal :
300
Exemple complet : 255
Décimal :
255
Binaire :
11111111
Hexadécimal :
FF
Octal :
377
C’est la valeur maximale d’un entier non signé sur un octet.
Elle apparaît donc naturellement dans beaucoup de contextes informatiques utilisant des champs de huit bits.
Exemple complet : caractère A
Caractère :
A
ASCII décimal :
65
ASCII hexadécimal :
41
Binaire :
01000001
Unicode :
U+0041
UTF-8 :
41
Exemple complet : caractère é
Caractère :
é
ASCII :
non représentable
Unicode :
U+00E9
UTF-8 :
C3 A9
Cet exemple résume parfaitement le passage :
ASCII
→
Unicode moderne
Pourquoi ces connaissances restent utiles aujourd’hui
Débogage
Les outils bas niveau affichent régulièrement :
- adresses en hexadécimal ;
- codes d’erreur ;
- octets mémoire ;
- flags binaires ;
- valeurs de registres.
Réseaux
Le binaire est indispensable pour comprendre :
- masques IPv4 ;
- CIDR ;
- adresses IPv6 ;
- adresses MAC ;
- champs de protocoles ;
- captures réseau.
Linux et Unix
L’octal apparaît constamment dans :
chmod 755
chmod 644
chmod 600
umask 022
Programmation bas niveau
Les représentations binaires et hexadécimales deviennent indispensables pour :
- masques de bits ;
- registres matériels ;
- protocoles ;
- drivers ;
- formats binaires ;
- reverse engineering ;
- débogage mémoire.
Web et graphisme
L’hexadécimal apparaît directement dans les couleurs :
#171A18
#FFFFFF
#FF0000
Texte et encodages
Comprendre ASCII, Unicode et UTF-8 aide à diagnostiquer :
- caractères corrompus ;
- mauvais encodages ;
- problèmes de fichiers texte ;
- problèmes de bases de données ;
- échanges entre systèmes.
Résumé à retenir
| Concept | À retenir |
|---|---|
| Binaire | Base 2, chiffres 0 et 1 |
| Bit | Un chiffre binaire |
| Octet | 8 bits, 256 combinaisons |
| Octal | Base 8, un chiffre représente 3 bits |
| Hexadécimal | Base 16, un chiffre représente 4 bits |
| ASCII | Codage sur 7 bits, valeurs 0 à 127 |
| Unicode | Répertoire moderne de points de code |
| UTF-8 | Encodage Unicode variable sur 1 à 4 octets |
Les règles essentielles
- Binaire, octal, décimal et hexadécimal sont différentes écritures de nombres.
- ASCII et Unicode sont des systèmes permettant d’associer des valeurs à des caractères.
- Un bit possède deux états possibles : 0 ou 1.
- Un octet contient exactement 8 bits et offre 256 combinaisons.
- Un entier non signé sur 8 bits varie donc de 0 à 255.
- Un chiffre hexadécimal représente exactement 4 bits.
- Un chiffre octal représente exactement 3 bits.
- Les permissions Unix utilisent naturellement l’octal parce que chaque groupe rwx contient trois bits.
755signifierwxr-xr-x.777accorde rwx à propriétaire, groupe et autres, mais ne décrit pas tous les bits spéciaux.- ASCII contient seulement les codes 0 à 127.
- Le code ASCII 0 s’appelle NUL, pas NULL.
- Le terminateur
'\0'des chaînes C est une convention du langage utilisant un octet nul. - 255 n’est pas un caractère ASCII.
- Dans un masque IPv4, 255 signifie simplement huit bits positionnés à 1.
- Unicode et UTF-8 ne sont pas synonymes : Unicode attribue les points de code, UTF-8 les encode en octets.
- UTF-8 conserve les caractères ASCII avec exactement les mêmes valeurs d’octets.
- Un caractère ne correspond pas nécessairement à un seul octet.
- Un motif de bits peut avoir des significations différentes selon le type de donnée utilisé pour l’interpréter.
Conclusion : les nombres ne changent pas, seulement leur costume
Le binaire, l’octal et l’hexadécimal deviennent beaucoup moins mystérieux lorsqu’on comprend qu’ils ne créent pas de nouveaux nombres.
Ils changent seulement leur représentation :
255
=
11111111₂
=
377₈
=
FF₁₆
ASCII ajoute ensuite une autre couche :
nombre
→ caractère
et Unicode généralise cette idée pour représenter les systèmes d’écriture du monde moderne.
La chaîne complète devient alors :
bits
↓
nombres
↓
points de code
↓
encodages
↓
caractères visibles
Une fois cette hiérarchie comprise, beaucoup de choses deviennent soudainement plus lisibles :
0xFF
255.255.255.0
chmod 755
#FFFFFF
U+00E9
C3 A9
Ce qui ressemblait auparavant à plusieurs dialectes obscurs devient simplement plusieurs façons de regarder les mêmes données.
Et si votre programme affiche encore :
é
à la place de :
é
ce n’est probablement plus la matrice qui vous attaque.
C’est presque certainement quelqu’un qui a mélangé ses encodages.
