Informatique


Le codage des caractères

Aller à


Wabief?

Les ordinateurs peuvent traiter autre chose que des nombres à commencer par manipuler des textes!
Mais comme on le sait l'ordinateur ne manipule que des informations binaires, celles-ci représentant du texte.

L'informatique s'est développée surtout aux États-Unis après la deuxième guerre mondiale, et la première langue qu'il fallait coder était l'anglais. Or, l'anglais s'écrit avec l'alphabet latin : il utilise donc 26 lettres (majuscules et minuscules), 10 chiffres, et quelques dizaines de signes de ponctuation. Au total, écrire l'anglais nécessite donc une centaine de caractères.

Les ordinateurs étant construits à partir de paquets de 8 bits (les bytes), et chaque byte étant capable de représenter 256 choses différentes, le choix était vite fait : on pouvait coder le texte sur le principe 1 caractère = 1 byte. Les valeurs des bytes qui ne correspondaient à aucun signe d'écriture pouvaient être utilisées pour représenter divers petits signes graphiques (des flèches, des mini-smileys, et des symboles variés).

Le problème, c'est que s'il existe une logique simple qui permet de coder les nombres en binaire, cette logique fait défaut en ce qui concerne les textes : la correspondance entre telle valeur de byte et tel signe alphanumérique est parfaitement arbitraire.
Du coup, dans les débuts de l'informatique, chaque concepteur d'ordinateur ou de logiciel avait créé sa propre table de correspondance. Mais du coup, les échanges de textes entre logiciels, ou entre machines, tournaient au casse-tête : le T majuscule de l'un devenait une parenthèse ouvrante chez l'autre !

C'est pourquoi dès le début des années 1960, on édicta un standard, une table de correspondance à laquelle tous devaient se plier ; cette table de correspondance, qui utilisait uniquement les 128 premières valeurs du byte (celles dont le premier bit est un zéro) est connue sous le nom de code ASCII (pour American Standard Code for Information Interchange). Dès lors, le A majuscule, par exemple, était codé par la valeur d'octet 01000001 (65, en notation décimale) quelle que soit la machine et le logiciel utilisés, et les textes pouvaient être transmis d'une machine à l'autre sans se changer en un charabia incompréhensible.

Le browser utilise une table de caractères de référence pour interpréter les caractères du fichier qui s'ouvre.
Dès lors, si cette table ne correspond pas à la table de caractères qui a été utilisée pour écrire le fichier les nombres binaires représentants les caractères ne correspondront pas parfaitement et l'affichage dans le browser sera altéré.

Le code suivant a été encodé avec la table de caractères ANSI (ou Windows-1252), qui est utilisé par le Blo-Notes de Windows.

Exemple d'une page web codée en ANSI
Démo
	<!doctype html>
	<html lang="fr">
	<head>
	</head>
	<body>
		çà va très bien
	</body>
	</html>

Le code ASCII

Le code ASCII (American Standard Code for Information Interchange), codé sur 7 bits, définit un jeu de 128 caractères numérotés de 0 à 127. Sept bits suffisent donc à les coder.
Cependant, comme la plupart des ordinateurs travaillent sur des données représentées sur un nombre de bits multiple de huit, les caractères ASCII sont codés sur un byte, le bit de poids fort étant 0.

Le jeu de caractères ASCII comprend:
  • les 26 lettres de l’alphabet latin en versions majuscules et minuscules,
  • les 10 chiffres
  • les symboles de ponctuation y compris l’espace
  • les couples de parenthèses, crochets et accolades
  • et quelques autres symboles divers
  • au clavier, ces caractères sont accessibles par la combinaison alt+codeAscii

Mais un gros souci apparaît! Les caractères nécessaires au anglo-saxons sont tous couverts, par contre, les caractères accentués des langues européennes ne peuvent être représentés car il n'y a pas assez de représentations possibles!

La table ASCII


Les extensions ISO-8859

Les codes ISO-8859 sont au nombre de 16 et désignés par ISO-8859-n où n est un entier compris entre 1 et 16.
Tous ces codes définissent chacun un jeu de 224 caractères codés de 0 à 127 et de 160 à 255 (les codes de 128 à 159 sont inutilisés).
Tous ces caractères sont représentés sur 8 bits.

Les caractères de codes compris entre 0 et 127 sont ceux du code ASCII. Les codes ISO-8859 se distinguent par le jeu des caractères de 160 à 255.
Pour avoir les caractères accentués du français il faut utiliser l’ISO-8859-1 (parfois appelé LATIN-1) ou l’ISO-8859-15 (parfois appelé LATIN-15) qui ne se distingue du précédent que par le remplacement de quelques caractères dont le ¤ par €. Avec ISO-8859-1 (ou ISO-8859-15), le é est codé 233.


UNICODE

Table UNICODE

Les diverses extensions du code ASCII, dont les ISO-8859, présentent l’inconvénient d’être incompatibles entre elles, et le plus souvent d’être spécialisées pour un jeu de caractères lié à une langue.
Comment alors coder dans un même document des textes rédigés avec des alphabets aussi divers que les alphabets latin, cyrillique, grec, arabe, ... ?

En 1990 on a développé un système d'encodage universel, Unicode, qui regroupe tous les caractères de toutes les langues de la planète.
Unicode en est actuellement à sa 15ième version (septembre 2023, version 15) et recense 149.813 caractères, attribue à chacun d’eux un "point code" exprimé sous la forme U+XXXX où XXXX représentent 4 chiffres hexadécimaux.

Les caractères de numéros compris entre:

  • 0 et 127 sont ceux du code ASCII
  • 160 et 255 sont ceux du code ISO 8859-1

Atteindre un caractère UNICODE avec JS
Démo
	<!doctype html>
	<html lang="fr">
	<head>
	</head>
	<body>
		Il suffit d'utiliser fromCharCode ou fromCodePoint
		<script>
		var monCarac = 65; //valeur en décimale
			console.log(String.fromCharCode(monCarac));
			console.log(String.fromCodePoint(monCarac));
		</script>
	</body>
	</html>


Des anglo-saxons pas contents

Les anglo-saxons on toujours pris l'habitude de coder les caractères en ASCII, table de codage n'exigeant que 8 bits (et même 7 pour l'ASCII de base), ils n'ont pas été très content de devoir tenir compte des autres langues parlées dans le monde et d'être donc obligés d'utiliser des tables de codages nécessitant plusieurs bytes par caractères!
... ce qui multipliait le poids des fichiers de 2, 3, 4 et parfois plus!

On a donc imaginé UNICODE et à partir de celui-ci un système de codage dynamique, pouvant compter de 1 à 4 bytes: utf-8 était né.

Les caractères ASCII étant tous regroupés dans le premier byte nos amis anglo-saxons se sont un peu calmés.


UTF-8, représentation binaire d'UNICODE

(Universal Character Set Transformation Format)

Unicode se contente de recenser, nommer et attribuer un nombre aux caractères. Mais il ne dit pas comment ils doivent être codés en binaire.

Plusieurs codages des caractères Unicode existent, le monde du Web utilise UTF-8 qui code chaque caractère sur 8, 16, 24 ou 32 bits (soit un, deux, trois ou quatre bytes). Mais il existe aussi:

  • UTF-16 qui code chaque caractère sur 16 ou 32 bits (soit deux ou quatre bytes)
  • UTF-32 qui code chaque caractère sur 32 bits (soit quatre bytes)


UTF-8

Le système est assez simple: Wikipédia

Jusqu'à 007F (127), 1 byte commençant par 0, le 0 indique qu'il y a 1 byte dans la représentation.

A U+0041 65 0100 0001
(100 0001)2 = (65)10

De 0080 (128) à 7FF(2047), 2 bytes commençant par 110 pour le premier et 10 pour le second.
La séquence 110 signifie qu'il y a 2 bytes, pour le second byte la séquence 10 signifie "bits de continuation".

é U+00E9 233 1100 0011 1010 1001
(1110 1001)2 = (233)10

De 0800 (2048) à FFFF(65535), 3 bytes commençant par 1110 pour le premier et 10 pour les suivants.
La séquence 1110 signifie qu'il y a 3 bytes, pour le second et le troisième byte la séquence 10 signifie "bits de continuation".

U+20AC 8 364 1110 0010 1000 0010 1010 1100
(10 0000 1010 1100)2 = (8 364)10

De 0800 (2048) à FFFF(65535), 3 bytes commençant par 1110 pour le premier et 10 pour les suivants.
La séquence 1110 signifie qu'il y a 3 bytes, pour le second et le troisième byte la séquence 10 signifie "bits de continuation".

𝄞 U+1D11E 119 070 1111 0000 1001 1101 1000 0100 1001 1110
(1 1101 000 10001 1110)2 = (119 070)10

On peut utiliser la syntaxe &#valeurDécimale; pour atteindre un caractère UTF-8.