La notion de jeu de caractères (charset en anglais) est une notion primordiale pour tout développeur web, et même, de façon plus générale, pour tout programmeur soucieux de préserver une certaine interopérabilité.
Pourtant, l'expérience prouve que cette notion reste fort abstraite dans l'esprit de beaucoup de ces développeurs, qui bien souvent ne la connaissent que par l'intermédiaire de la ligne <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
, et qui s'imaginent
dès lors que la simple modification de cette ligne permet de changer de jeu de caractères. Il n'en est rien. Nous allons tenter ici d'éclaircir certains points.
Les jeux de caractères que l'on rencontre le plus souvent de notre côté occidental de l'internet sont l'ISO-8859-1, l'UTF-8 et, par la force des choses, le Windows-1252, jeu qui pose quelques problèmes de validité (X)HTML , et dont je parlerai plus loin.
Une histoire de bits
Chacun sait qu'un ordinateur est une machine fonctionnant grâce à des calculs binaires (1 ou 0), pour la simple mais bonne raison qu'il est bien plus facile de représenter un nombre en base binaire (qui ne requiert que deux états, en l'occurence "courant" ou "pas courant") qu'en base 10 (qui nécessiterait de distinguer dix états physiques). Par voie de conséquence, les fichiers sont eux aussi stockés sous la forme d'une suite de bits, chaque bit ayant la valeur 0 ou 1. Ce sont ces bits que vous voyez lorsque vous éditez un fichier à l'aide d'un éditeur hexadécimal, car chaque valeur hexadécimale (base 16) correspond à 4 bits.
Dans ce cadre, le jeu de caractère est la façon de représenter chaque caractère (et donc un texte) dans cette base binaire. La plupart des jeux de caractères étant codés sur un octet, soit huit bits, chaque caractère de votre fichier texte correspondrait à une paire de chiffres dans un éditeur hexadécimal. On comprend alors que cette notion est tout ce qu'il y a de plus concret. En effet, tout comme ouvrir un fichier généré par un programme dans un autre programme peut poser quelques difficultés pour des raisons d'encodage de l'information, tenter de visionner un fichier texte (ou une page HTML, qui n'est jamais qu'un fichier texte amélioré) utilisant un certain jeu de caractère à l'aide d'un éditeur ou d'un navigateur gérant un autre jeu de caractère peut amener des résultats étranges, comme la substitution d'un caractère par un autre, ou peut-être un message d'erreur, si aucun caractère du jeu utilisé par le programme ne correspond à la paire hexadécimale renseignée dans le fichier.
Maintenant que vous savez ce qu'est un jeu de caractère, détaillons-en quelques-uns...
Un petit bout d'histoire
Le premier de tous fut l' ASCII . Il était codé sur huit bits. Mais dans ces huits bits, seuls sept représentaient une information, le huitième étant un dispositif de sécurité, ce qu'on appelle un bit de parité, pour pallier à la relativement faible fiabilité du matériel mis en oeuvre. Ce bit de parité permettait de détecter une éventuelle erreur qui serait survenue lors de la transmission de l'octet. On disposait donc de 7 bits pour coder le caractère, ce qui donnait un total de 128 combinaisons possibles, et donc de 128 caractères représentables (Remarque : il fut décidé que le bit de parité, dont l'étude sort du cadre de cet article, soit en fait positionné en première position parmi les 8 bits utilisés pour représenter le caractère).
L'ASCII était peut-être suffisant pour échanger de sommaires informations en anglais, mais ne l'était pas pour représenter les autres langues du monde occidental. On décida donc d'«étendre» ce jeu de caractère en utilisant le premier bit de l'octet pour coder lui-aussi une information, laissant ainsi tomber le bit de parité. On obtient donc un jeu étendu de 8 bits utiles, soit 256 caractères représentables, dont les 128 premiers sont communs à tous les jeux étendus, car issus de l'ancêtre commun (ASCII). De nombreux jeux étendus ont vu le jour, pour coder des langues comme le grec ou le russe (alphabet cyrillique), mais aussi pour coder les langues d'Europe occidentale, en intégrant accents et signes de ponctuations qui nous sont propres. Standardisé par l'Organisation internationale de normalisation (ISO), l'ISO-8859-1, ou ISO-Latin1 était né.
D'autres jeux très répandus sont des variantes de l'ISO-8859-1, comme par exemple le récent ISO-8859-15 (qui est un ISO-8859-1 modifié pour pouvoir contenir des symboles comme le sigle €, trop récent pour être inclus dans la norme originale, ou œ, d'abord oublié pour je-ne-sais quelle raison obscure), ou les jeux propriétaires MacRoman (pour MacOs) et Windows-1252, pour Windows. C'est ce dernier plus particulièrement qui pose quelques problèmes, car de nombreuses pages renseignées comme ISO-8859-1 sont en fait encodées en Windows-1252, ce qui a poussé les navigateurs, du moins sous Windows, à systématiquement représenter les pages renseignées comme utilisant l'ISO-8859-1 (sans distinction) à l'aide du jeu de caractères Windows-1252.
La variété des jeux étendus est comme une preuve éclatante de leur insuffisance. En effet, 256 caractères, ce n'est pas beaucoup, et ça rend surtout impossible la rédaction d'un document en plusieurs langues. Oublions donc tout de suite le document texte reprenant des mots japonnais et leur traduction en français. Ont donc vu le jour des jeux de caractères codés sur deux octets, comme l'UCS-2 (Universal Character Set), ce qui porte le nombre de caractères représentables de 256 à 65536, ce qui est somme toute confortable. Il existe aussi des jeux de caractères codés sur 32 bits, comme l'UCS-4 (plus de 4 milliards de caractères représentables).
Cependant, on perd alors une caractéristique intéressante des jeux étendus : leur compatibilité en ce qui concerne les 128 premiers caractères, communs, ce qui permet de les utiliser indifféremment pour encoder une page HTML ou même un code source, par exemple en PHP, sans devoir multiplier les fonctions d'interprétation. En effet, les langages de programmation n'utilisent bien souvent que les caractères issus de la norme ASCII. Dans le même ordre d'idées, il devient difficile (voire impossible dans le cas de processus automatiques) de déchiffrer un fichier texte UCS-2 dans un éditeur qui n'est pas prévu pour lui. Nous voici donc confronté à un problème plus sérieux : comment créer un jeu de caractères offrant la possibilité de représenter de nombreux caractères, sans pour autant perdre la compatibilité avec l'ASCII ?
La solution fut d'utiliser un nombre d'octets variable pour représenter les caractères. Ce jeu-miracle s'appelle l'UTF-8 (Unicode Transformation Format). On utilise ainsi entre 1 et 4 octets pour représenter un caractère, en introduisant une convention pour différencier les octets isolés, représentant à eux seuls un caractère, ou les octets groupés, devant être considérés à plusieurs pour pouvoir en extraire l'information. Pour conserver la compatibilité avec l'ASCII et les jeux étendus, il a été décidé que les octets isolés commenceraient par un 0. Cette norme permet de représenter un nombre impressionnant de caractères différents, sans compter le fait qu'elle permet un autre système de représentation, l'agrégation de glyphes, que je ne détaillerai pas ici. Seuls un peu plus de 90000 caractères ont été attribués pour l'instant.
Une chose importante à savoir à propos de l'UTF-8, c'est qu'il existe en deux variantes : avec ou sans BOM (Byte Order Mark) . La BOM est en quelque sorte une signature, présente en tout début de fichier, et permettant de reconnaître un fichier encodé avec UTF-8, et de connaitre l'ordre (big endian ou little endian) dans lequel seront présentés les octets des différents caractères (ce mécanisme existe aussi pour d'autres jeux de caractères multi-octets). Elle est rare car non requise, et, comme dans notre cas particulier, elle présente une information redondante avec les en-têtes fournis par le serveur et l'en-tête XML, elle est inutile et sera donc omise pour éviter tout problème avec des programmes ne la reconnaissant pas.
Exemples de codes
Caractère | ASCII | ISO-8859-1 | UTF-8 | UCS-2 | UCS-4 |
---|---|---|---|---|---|
e (1) | 01100101 | 01100101 | 01100101 | 00000000 01100101 | 00000000 00000000 00000000 01100101 |
é (2) | — | 11101001 | 11000011 10101001 | 00000000 11101001 | 00000000 00000000 00000000 11101001 |
? (3) | — | — | 11100001 10111010 10111001 | 00011110 10111001 | 00000000 00000000 00011110 10111001 |
1 : le caractère e appartient aux caractères communs à l'US-ASCII et à tous les jeux étendus, son code commençant par 0 est identique en ASCII, ISO-8859-1 et UTF-8; Mais cette compatibilité est perdue avec UCS-2 et UCS-4.
2 : le caractère é ne peut être représenté en US-ASCII. L'exploitation du premier bit de l'octet permet sa représentation en ISO-8859-1. En UTF-8, il est codé sur 2 octets.
3 : le caractère ? n'appartient pas aux langues couvertes par ISO-8859-1, et ne peut être représenté par ce codage. Codé sur 3 octets, il peut cependant être représenté en UTF-8.
Les outils
On comprend maintenant qu'il ne suffit pas de décider d'utiliser un jeu de caractères pour l'utiliser de façon effective. Encore faut-il que le programme d'édition le gère. Voici quelques logiciels, libres ou gratuits, qu'il est possible d'utiliser pour encoder les pages en UTF-8 ou en ISO-8859-1 (se reporter à leurs options et dans leurs fichiers d'aide respectifs pour plus de détails) :
- Unired : petit éditeur, sous Windows uniquement. Gère la coloration syntaxique pour de nombreux formats de documents, et gère une cinquantaine de jeux de caractères différents.
- Jext : éditeur écrit en Java, et donc accessible sur toutes les plateformes. Il gère la coloration syntaxique pour de nombreux formats de documents, et gère l'UTF-8 et ISO-8859-1, mais de façon bien moins souple qu'Unired.
- SciTE : éditeur très léger, sous Windows et Linux, qui gère la coloration syntaxique, l'UTF-8 et l'ISO-8859-1, de façon très souple. L'un de mes préférés. Attention, dans le cas de SciTE, l'enregistrement sans BOM se fera en sélectionnant le jeu «UTF-8 Cookie».
- Vim et Emacs, sans doute les plus célèbres éditeurs de texte de l'univers du logiciel libre.
- JEdit, BBEdit, PSPad, etc.
Compléments d'information :
- Qu'est-ce qu'Unicode ?
- Unicode
- Entité dans un document HTML (Karl Dubost)
- Codage valide des caractères Windows illégaux en HTML et XHTML (Laurent Denis)
- Tutorial : Character sets & encodings in XHTML, HTML and CSS (Richard Ishida)
- Characters and encodings (Jukka Korpela)
- Forms of Unicode (Mark Davis)
Vos commentaires
# Philippe Durand Le 15 août 2010 à 19:30
Bonjour,
Dans votre article vous tentez une approche historique des codages des caractères et vous annoncez que l’ancêtre est l’ASCII sur 7 bits plus parité. Vous ignorez toute une partie de l’histoire qui commence avant l’ère informatique.
Avant que l’homme ne sache réaliser une machine répondant aux études de Pascal et Leibnitz, la notion de codage était déjà connue. La découverte faite par l’homme et par accident par Volta de l’énergie électrique est aussi arrivée bien avant les "calculateurs" et très rapidement aux Etats Unis, les scientifiques ont mélangé le codage et l’électricité : ils venaient de découvrir "Le fil qui chante", autrement mieux connu sous le terme de télégraphe.
Au début il ont utilisé le code morse qui était décodé directement par un opérateur instruit. Ce code ne connaissait que les lettres, les chiffres et quelques signes de ponctuation.
L’introduction du ruban papier se fait dès le début du 20ième siècle, il permet toutes sortes de transmissions rapides avec les lecteurs motorisés connectés sur des machines à écrire. On en voit un exemple dans le film l’Arnaque, où le bureau du bookmaker de Chicago reçoit en direct par Telex les résultats des courses. C’est là que nous trouvons un constructeur de machines à écrire, International Business ... , (hé oui) en Europe Olivetti, LogAbax et bien d’autres construisaient aussi des machines de bureau, leurs évolutions vers le calcul électronique est une suite logique.
Les dispositifs de transmission électromécaniques n’avaient pas une grande bande passante et le code du télégraphe fut adapté pour qu’il devienne facilement transportable sur le "fil qui chante" sans reconstruire un nouveau réseau. La aussi je m’ose un autre parallèle, les chercheurs qui ont développé l’ADSL, s’étaient imposé le support physique (couche 1) existant comme contrainte, la raison économique est assez évidente. Ils devaient coder 26 lettres 10 chiffres et quelques symboles de ponctuation, ils ont utilisé un codage sur 5 bits plus parité.
Ils utilisaient la position haute et la position basse de la machine à écrire, une touche permettant de faire glisser dans son bâti toute la mécanique d’impression, les bras qui frappaient sur le papier pouvaient ainsi imprimer chacun deux caractères. Le codage sur 5 bits offrait 30 caractères par positionnement, les caractères de positionnement étant commun aux deux.
Et comment dit-on glisser en anglais ? " shift ".
Notre touche shift doit son nom au télex qui fut le premier système de transmission électronique standardisé mondialement. Le télex est mort dans la seconde moitié du XX ième siècle, à cette époque les équipements d’extrémité étaient quasiment tous construits par le constructeur : Teletype. C’est l’abbréviation de son nom qui devint le nom de code des premiers terminaux asynchrone d’Unix dans les années 70 : TTY.
Ce code à 5 bits + parité était encore utilisé par les ordinateurs ITT 3200, à la fin des années 70, qui pilotaient les centraux Metaconta qui furent commandés par la DGT et Norbert Segard quand la France se fut décidée à moderniser son réseau téléphonique.
Ce code est encore connu sous le nom d’Alphabet CCITT numéro 3.
Le CCITT N3 était très pauvre, l’apparition des modems et de l’informatique a permis d’envisager des débits bien supérieurs à ceux du télex, dès lors qu’il n’y avait plus de système à moteur électrique tournant pour encoder les caractères sur la ligne de transmission. On put ainsi élargir les caractères et passer à 7 bits + parité. L’alphabet CCITT N.5 était né ; il permettait, enfin, une représentation presque correcte des différentes langues simples, l’anglais tient complètement dans ce codage. Par contre pour les français on pouvait disposer des minuscules accentuées et des signes diacritiques au prix de la perte de certains caractères spéciaux comme les parenthèses, accolades et certains symboles monétaires.
La programmation en C nécessitait de changer de page de code.
C’est seulement à partir d’ici que l’on reprend votre article.
Désolé d’avoir été long, mais j’ai débuté en 1973 et suis toujours en activité, j’ai participé à toute l’évolution du télex et de la téléphonie, à la téléinformatique, puis à x25 et à la télématique pour se terminer avec TCP/IP et les réseaux à très haut débit.
Si ce papier vous intéresse, je peux le réécrire en l’approfondissant afin que toute cette préhistoire soit bien expliquée et que l’on puisse voir dans les technologies actuelles les restes des balbutiements.
Philippe Durand
# Le 23 septembre 2010 à 13:47 En réponse à : Philippe Durand
Approfondissez, approfondissez !! Et merci pour la leçon d’histoire. Il est toujours intéressant de pouvoir considérer dans un contexte historique les "technologies" actuelles.
Hubert.
# edjay Le 20 février 2011 à 13:34 En réponse à : Philippe Durand
C’est très intéressant, cela mériterait quelques pages.
Merci beaucoup.
# sebounet Le 20 mars 2011 à 10:53
@Philippe Superbe ! Merci pour le cours...
Merci à toi aussi Steve, très instructif tout ça. Je me permet de donner une référence supplémentaire http://www.cs.tut.fi/~jkorpela/chars.html
++
# Le 3 mai 2011 à 04:11
Bonjour,
Juste un petit mot pour tous vous remercier !
J’ai des probleme d’encodage entre le php et le javascript et ma base de donnee, et grace a ce texte je comprend mieux la profondeur de la chose.
Merci encore !!
# Jean-Marie Galliot Le 29 septembre 2012 à 23:58
J’ai toujours eu de la difficulté avec l’encoding. Alors j’avais décidé de ne pas mourir idiot. J’ai donc fait un peu de recherche et je suis tombé sur cet article. Merci pour sa clarté ! C’est rare que nos jours !
Je ne comprends pas pourquoi, cependant, vous dites que le point d’interrogation n’existe pas dans la jeu ISO-8859-1 ?
Peut-être est-ce une erreur typographique dans votre article.
En tous cas merci.
(et pour ce qui est du code morse, je le connait déjà, merci d’avoir fait l’impasse ;-)
# Aurélien Le 27 février 2014 à 12:03
Miam Miam votre commentaire Philippe. Merci !
OpenWeb serait une très bonne tribune pour recueillir vos propos.
# Anonyme Z Le 5 janvier 2015 à 03:06
?
:?: ils sont différends de
?
ISO-8859-1 11101001 E9 →
UTF-8 11000011 10101001 C3 A9
Ã
# Anonyme Z Le 5 janvier 2015 à 03:07
à Jean-Marie Galliot
1)Avant-propos
ISO-8859-1 11101001 E9
UTF-8 11000011 10101001 C3 A9
C3 en Latin-1 Ã
A9 en Latin-1 ©
Une page UTF-8 contenant é (C3A9) devient en Latin-1 é
exemple :
accélérer(UTF-8) devient accélérer (Latin-1)
2) Commentaire sur "Exemple de code" ? (3)
Dans le tableau on a
11100001 10111010 10111001 → E1BAB9 → ẹ
→Latin Small Letter E With Dot Below
→UTF-8 (Hex) : E1BAB9
→Unicode (Hex) : 01EB9
11100001 10111010 10111001 donne ẹ et non ?
Par contre il existe un caractère unicode qui ressemble à ? mais n’est pas ?
c’est le caractère suivant ?
et voiçi ses caractéristiuqes
11101111 10111100 10011111→EFBC9F→?
?Fullwidth Question Mark
Unicode (Hex) : 0FF1F
UTF-8 (Hex) : EFBC9F
il est différend de ?
Question Mark
Unicode (Hex) : 0003F
UTF-8 (Hex) : 3F
D’ailleurs ?peut être utilisé dans les noms de fichiers mais pas ?
Et aussi :peut être utilisé dans les noms de fichiers mais pas :
de quoi rendre fou ceux et celles qui ne connaissent pas ces caractères unicodes :-)
Fullwidth Colon :
Unicode (Hex) : 0FF1A
UTF-8 (Hex) : EFBC9A
Colon :
Unicode (Hex) : 0003A
UTF-8 (Hex) : 3A
# Anonyme Z Le 5 janvier 2015 à 03:10
Pour trouver tous les caractères unicodes voiçi un site utile :
http://www.isthisthingon.org/unicode/index.phtml
# Franck F. Le 20 octobre 2015 à 21:44
Y-a-t-il d’autres jeux de caractères ou langages issus d’un alphabet autre que celui cyrillique ?
# murelle Le 10 octobre 2016 à 14:14
bonjour mesdames
# murelle Le 10 octobre 2016 à 14:15
èutyttytytyt
# De Luca Le 16 octobre 2017 à 10:49
Bonjour, félicitations pour vos informations. Pourriez-vous m’informer comment je peux m’y prendre afin de corriger les é,è ect.. remplacés par des ?. sur le site que j’ai créé et ce problème est intervenu il y a environ trois mois, suite à une mise à jour , je suppose.
Les erreurs de sécurité mentionnées, sont SEC7113 et HTML1114.
Merci de votre patience, je ne suis pas un pro en informatique. Bonne journée.
# Ching Le 4 février 2019 à 23:41
7 bits pour coder un caractère c’est 2⁷-1 = 127 possibilités de caractères plutôt que 128.
Vos commentaires
Suivre les commentaires : |