<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://openweb.eu.org/dtd/docbkx42/docbookx.dtd">
<article xml:lang="fr" lang="fr" id="jeux_caracteres" role="article">
  <articleinfo>
    <title>Introduction aux jeux de caractères</title>
    <author>
      <firstname>Steve</firstname>
      <surname>Frécinaux</surname>
			<email>nudrema@gwash.com</email>
    </author>
    <abstract>
      <para>Qu'est-ce qu'un jeu de caractères ? Quelle est la différence entre <acronym>ISO</acronym>-8859-1, <acronym>UTF</acronym>-8 et Windows-1252 ? Steve Frécinaux nous présente les différents jeux de caractères.</para>
    </abstract>
    <pubdate>2004-07-12</pubdate>
    <date>2004-07-12</date>
    <subjectset>
      <subject role="profil">
        <subjectterm>expert</subjectterm>
        <subjectterm>debutant</subjectterm>
      </subject>
      <subject role="technologie">
        <subjectterm>xhtml</subjectterm>
      </subject>
      <subject role="theme"/>
		</subjectset>
    <legalnotice>
      <para>Cet article est sous licence <ulink url="http://creativecommons.org/licenses/by-sa/1.0/legalcode">Creative Commons Attribution-ShareAlike</ulink>.</para>
    </legalnotice> 
  </articleinfo>
  <para>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 <token>&lt;meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" /&gt;</token>, 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.</para>
  <para>Les jeux de caractères que l'on rencontre le plus souvent de notre côté occidental de l'internet sont 
l'<acronym>ISO</acronym>-8859-1, 
l'<acronym>UTF</acronym>-8 et, par la force
des choses, le Windows-1252, jeu qui pose <ulink url="/articles/caracteres_illegaux/">quelques problèmes de validité <acronym>(X)HTML</acronym></ulink>, et dont je parlerai plus loin.</para>
  <section id="bits">
    <title>Une histoire de bits</title>
    <para>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.</para>
    <para>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 <acronym>HTML</acronym>, 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.</para>
    <para>Maintenant que vous savez ce qu'est un jeu de caractère, détaillons-en quelques-uns...</para>
  </section>
  <section id="histoire">
    <title>Un petit bout d'histoire</title>
    <para>Le premier de tous fut l'<ulink url="http://fr.wikipedia.org/wiki/ASCII">
        <acronym>ASCII</acronym>
      </ulink>.
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&#160;: 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).</para>
    <para>L'<acronym>ASCII</acronym> é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 (<acronym>ASCII</acronym>). 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'<ulink url="http://fr.wikipedia.org/wiki/ISO">Organisation internationale de normalisation</ulink> (<acronym>ISO</acronym>), l'<ulink url="http://fr.wikipedia.org/wiki/ISO_8859-1">ISO-8859-1</ulink>, ou ISO-Latin1 était né.</para>
    <para>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 &#8364;, 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 <ulink url="http://worldserver3.oleane.com/tthomas/jeucar.html">Windows-1252</ulink>, 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.</para>
    <para>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 (<ulink url="http://en.wikipedia.org/wiki/Universal_character_set">Universal Character Set</ulink>), 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).</para>
    <para>Cependant, on perd alors une caractéristique intéressante des jeux étendus&#160;: leur compatibilité en ce qui
concerne les 128 premiers caractères, communs, ce qui permet de les utiliser indifféremment pour encoder une page
<acronym>HTML</acronym> ou même un code source, par exemple en 
<acronym>PHP</acronym>, 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 <acronym>ASCII</acronym>. 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&#160;: 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'<acronym>ASCII</acronym>&#160;?</para>
    <para>La solution fut d'utiliser un nombre d'octets variable pour représenter les caractères. Ce jeu-miracle s'appelle
l'<ulink url="http://fr.wikipedia.org/wiki/UTF-8">UTF-8</ulink> (Unicode Transformation Format). On utilise ainsi entre 1 et 6 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'<acronym>ASCII</acronym> 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.</para>
    <para>Une chose importante à  savoir à  propos de l'UTF-8, c'est qu'il existe en deux variantes&#160;: avec ou sans
<ulink url="http://en.wikipedia.org/wiki/Byte_Order_Mark">
        <acronym title="Byte Order Mark" lang="en">BOM</acronym> (Byte Order Mark)
      </ulink>. La <acronym title="Byte Order Mark" lang="en">BOM</acronym> 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 (<emphasis>big endian</emphasis> ou <emphasis>little endian</emphasis>) 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
<acronym>XML</acronym>, elle est inutile et sera donc omise pour éviter tout
problème avec des programmes ne la reconnaissant pas.</para>
  </section>
  <section id="exemples">
    <title>Exemples de codes</title>
    <table>
      <tgroup cols="6">
        <thead>
          <row>
            <entry>Caractère</entry>
            <entry>ASCII</entry>
            <entry>ISO-8859-1</entry>
            <entry>UTF-8</entry>
            <entry>UCS-2</entry>
            <entry>UCS-4</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>e (<ulink url="#exemple-1">1</ulink>)</entry>
            <entry>01100101</entry>
            <entry>01100101</entry>
            <entry>01100101</entry>
            <entry>00000000 01100101</entry>
            <entry>00000000 00000000 00000000 01100101</entry>
          </row>
          <row>
            <entry>é (<ulink url="#exemple-2">2</ulink>)</entry>
            <entry>—</entry>
            <entry>11101001</entry>
            <entry>11000011 10101001</entry>
            <entry>00000000 11101001</entry>
            <entry>00000000 00000000 00000000 11101001</entry>
          </row>
          <row>
            <entry>ẹ (<ulink url="#exemple-3">3</ulink>)</entry>
            <entry>—</entry>
            <entry>—</entry>
            <entry>11100001 10111010 10111001</entry>
            <entry>00011110 10111001</entry>
            <entry>00000000 00000000 00011110 10111001</entry>
          </row>
        </tbody>
      </tgroup>
    </table>
    <para id="exemple-1">1&#160;: le caractère <emphasis role="strong">e</emphasis> 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.</para>
    <para id="exemple-2">2&#160;: le caractère <emphasis role="strong">é</emphasis> 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.</para>
    <para id="exemple-3">3&#160;: le caractère <emphasis role="strong">ẹ</emphasis> 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.</para>
  </section>
  <section id="outils">
    <title>Les outils</title>
    <para>On comprend maintenant qu'il ne suffit pas de <emphasis>décider</emphasis> 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)&#160;:</para>
    <itemizedlist>
      <listitem>
        <ulink url="http://unired.sourceforge.net/">Unired</ulink>&#160;: 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.
      </listitem>
      <listitem>
        <ulink url="http://jext.sourceforge.net/">Jext</ulink>&#160;: é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.
      </listitem>
      <listitem>
        <ulink url="http://www.scintilla.org">SciTE</ulink>&#160;: é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 <acronym xml:lang="en">BOM</acronym> se
  fera en sélectionnant le jeu «UTF-8 Cookie».
      </listitem>
      <listitem>
        <ulink url="http://www.vim.org">Vim</ulink> et <ulink url="http://www.gnu.org/software/emacs/">Emacs</ulink>, sans doute les plus célèbres éditeurs de texte de l'univers du logiciel libre.
      </listitem>
      <listitem>
        <ulink url="http://www.jedit.org">JEdit</ulink>, <ulink url="http://www.barebones.com/products/bbedit/index.shtml">BBEdit</ulink>, <ulink url="http://www.pspad.com/">PSPad</ulink>, etc.
      </listitem>
    </itemizedlist>
  </section>
  <section id="complements">
    <title>Compléments d'information&#160;:</title>
    <itemizedlist>
      <listitem>
        <ulink url="http://www.unicode.org/standard/translations/french.html">Qu'est-ce qu'Unicode&#160;?</ulink>
      </listitem>
      <listitem>
        <ulink url="http://fr.wikipedia.org/wiki/Unicode">Unicode</ulink>
      </listitem>
      <listitem>
        <ulink url="http://www.la-grange.net/2002/10/23#entite">Entité dans un document HTML</ulink> (Karl Dubost)
      </listitem>
      <listitem>
        <ulink url="/articles/caracteres_illegaux/">Codage valide des caractères Windows illégaux en HTML et XHTML</ulink> (Laurent Denis)
      </listitem>
      <listitem>
        <ulink url="http://www.w3.org/International/tutorials/tutorial-char-enc/">Tutorial&#160;: Character sets &amp; encodings in XHTML, HTML and CSS</ulink> (Richard Ishida)
      </listitem>
      <listitem>
        <ulink url="http://www.cs.tut.fi/~jkorpela/chars/index.html">Characters and encodings</ulink> (Jukka Korpela)
      </listitem>
      <listitem>
        <ulink url="http://www-106.ibm.com/developerworks/library/utfencodingforms/">Forms of Unicode</ulink> (Mark Davis)
      </listitem>
    </itemizedlist>
  </section>
</article>
