Encore plus de jeux de caractères : ISO/CEI 10646 et Unicode?

Dans les deux articles précédents, Jeux de caractères : Morse, ASCII, ISO/CEI 646? et Encore des jeux de caractères : ISO 8859-1, MacRoman, CP1252?, nous avons survolé deux normes ISO pour l’encodage de l’alphabet latin : l’ISO/CEI 646 (sur 7 bits) et l’ISO/CEI 8859 (sur 8 bits).

Pour chacune de ces normes, nous avons vu qu’il existait plusieurs variantes en partie incompatibles entre elles, et que si nous avions considéré les caractères grecs, arabes ou japonais, nous aurions probablement perdu le peu de sens commun qui nous guidait jusque-là.

Heureusement, à la fin des années 80, des travaux ont été entâmés pour définir un standard universel. Autrement dit, un seul et unique jeu de caractères qui comprendrait tous les caractères qui existent!

Seul hic, deux organismes ont entrepris à peu près à la même époque de définir ce nouveau jeu de caractères… l’Organisation internationale de normalisation (ISO) et le Consortium Unicode.

Cependant, pour le bien commun, les deux organismes collaborent étroitement entre elles et elles définissent exactement le même jeu de caractères (correspondances entre les versions). Malgré tout, il reste que la confusion est encore grande entre les deux, mais nous pouvons retenir que l’ISO/CEI 10646 et l’Unicode sont des standards qui vont bien au-delà du jeu de caractères universel.

De toute manière, dans notre survol, nous regarderons seulement les principes communs aux deux normes.

Le Consortium Unicode

Le Consortium Unicode est un organisme à but non-lucratif incorporé en Californie en 1991. Le président et cofondateur est Mark Davis (à l’époque chez Apple, puis chez IBM et maintenant chez Google…) qui tient un site Web au nom original pour les amateurs de café : http://www.macchiato.com/.

Le consortium compte parmi ses membres tous les grands noms des technologies informatiques, notamment, depuis sa fondation, Apple, Microsoft et IBM.

Le nom « Unicode » fait référence à un jeu de caractères universel, uniforme et unique.

Le jeu de caractères universel (Universal Character Set ou UCS)

Contrairement aux autres jeux de caractères, les normes ISO/CEI 10646 et Unicode apportent une innovation simple mais extrêmement intéressante : elles séparent le jeu de caractères universel de son implémentation.

Effectivement, nous avons vu précédemment que les jeux de caractères avaient pour but d’associer chaque caractère à une forme prédéterminée, que ce soit un nombre binaire sur 7 bits, 8 bits ou plus (une séquence de 8 bits est appelée un octet).

Au contraire, le jeu de caractères universel a pour mission d’assigner un numéro unique, appelé point de code, à tous les caractères qui existent, peu importe la forme d’encodage utilisée en pratique, que ce soit l’UTF-8, l’UTF-16 ou l’UTF-32, que nous verrons plus loin. Aussi, un point de code ne peut pas être retiré une fois qu’il a été assigné, peu importe la version de la norme.

Ainsi, chaque caractère de l’UCS est officiellement défini par son point de code (en hexadécimal, c.-à-d. en base 16 plutôt qu’en base 10) et une description (pourquoi définit-on les points de code en hexadécimal et non en décimal? voir l’annexe : Notation hexadécimale).

Par exemple, voici la définition de la lettre minuscule « e » : 0065   e   LATIN SMALL LETTER E

D’ailleurs, nous pouvons noter que 6516 est aussi le code ASCII du caractère « e », car les 256 premiers points de code de l’UCS sont ceux de l’ISO-8859-1 (lui-même compatible avec l’ASCII).

Notes importantes sur la définition d’un caractère :

  1. Un point de code est normalement noté en ajoutant « U+ » devant. Par exemple, le point de code du caractère « e » est U+0065. Voici une autre charte des points de code.
  2. Le caractère « e » est une entité abstraite, c.-à-d. qu’il est indépendant de la police et du style. L’UCS n’encode pas les glyphes qui composent les polices de caractères, car ceux-ci relèvent de la présentation du caractère et non de sa signification. Donc, « e » , « e » et « e » sont tous équivalents. Par contre, il différencie les lettres majuscules des lettres minuscules.
  3. Le caractère « e » est défini comme un caractère « latin », car les caractères de l’UCS sont regroupés par langues, ou par scripts, selon la terminologie de l’Unicode.

Les plans de l’UCS et le plan multilingue de base

Le jeu de caractères universel est découpé en 17 plans, de 0 à 16, de 65536 caractères possibles, c.-à-d. de 16 bits chacun. Puisque les points de code sont assignés en hexadécimal, nous devons en déduire que le plan 0 comprend les codes 000016 à FFFF16, le plan 1, les codes 1000016 à 1FFFF16 et ainsi de suite jusqu’au plan 16 de 10000016 à 10FFFF16 (rappelons-nous que 10 en hexadécimal est égal à 16 en décimal).

La plupart des langues courantes se trouvent dans le plan 0, couramment appelé plan multilingue de base (PMB). Il est donc possible de représenter ce plan en entier sur 16 bits (donc 2 octets).

Les formes d’encodage de l’UCS : UTF-8, UTF-16 et UTF-32

L’UCS peut être encodé dans des formes diverses, c.-à-d. avec un nombre d’octets fixe ou variable.

Voici les formes (Universal Transformation Format ou UTF) possibles :

Forme Encodage Caractéristiques principales
UTF-8 sur 1 à 4 octets Les 128 premiers caractères sont encodés sur 1 octet. Cette forme est donc compatible avec l’US-ASCII. Au-delà, les caractères sont encodés sur 2, 3 ou 4 octets.
UTF-16 sur 2 ou 4 octets Tous les points de code qui tiennent sur 2 octets, c.-à-d. les caractères du plan multiling de base – à l’exception de la plage U+D800 à U+DFFF -, sont encodés sur 2 octets.
UTF-32 sur 4 octets Forme la plus simple mais qui consomme le plus d’espace disque. Bien que 3 octets seraient suffisants pour encoder tous les caractères jusqu’à 10FFFF16, les 4 octets permettront un jour d’étendre l’UCS au-delà de cette limite.

À noter que bien que les points de code de l’UCS soient compatibles avec l’ISO-8859-1, aucune des formes d’encodage n’est compatible avec celui-ci, sauf l’UTF-8, qui est seulement compatible avec la portion US-ASCII.

Jeu de caractères Caractère « é »
(en hexadécimal / point de code)
Caractère « é » encodé
(en hexadécimal)
ISO-8859-1 E9 E9
UTF-8 U+00E9 C3A9
UTF-16 U+00E9 00E9
UTF-32 U+00E9 0000 00E9

Forme composée et forme décomposée

Un principe de l’unicode qui peut être une source de confusion est la composition de caractère. Avec l’unicode, il est possible d’encoder certains caractères de plusieurs façons, indépendamment de la forme d’encodage.

Par exemple, nous pouvons encoder le caractère « è », soit en encodant le caractère directement, soit en encodant le « e » puis le « ` » séparément :

  • Forme composée : « è » => U+00E8
  • Forme décomposée : « e » + « ` » => U+0065 U+0300

Les accents ou diacritiques les plus communs se trouvent sur la plage U+0300 à U+036F (Combining Diacritical Marks).

À noter que la forme décomposée est souvent utilisée dans certains composants de MacOS X, tels que le client WebDAV. Cette utilisation a même donné naissance à ce qu’on appelle le UTF8-MAC.

Pour les programmeurs Java, mentionnons que depuis Java 1.6, la classe java.text.Normalizer permet de composer et de décomposer du texte Unicode.

Support et affichage de l’UCS/Unicode

Bien qu’il soit assez bien supporté par les plateformes les plus populaires, ce n’est pas tous les caractères de l’Unicode, même du plan multilingue de base, qui sont supportés. L’affichage de certains scripts peut dépendre du système d’exploitation et du navigateur utilisé.

N’oublions pas que l’UCS définit seulement la table des caractères abstraits et de leurs points de code respectifs. Pour afficher un caractère, il faut au moins une police de caractères qui le contienne.

Lorsqu’un caractère n’est pas supporté, on peut voir le rectangle ouvert, un rectangle contenant son point de code (entre autres sous Firefox) ou le caractère de remplacement de l’UCS (U+FFFD, �).

D’ailleurs, le rectangle ouvert n’est pas un caractère comme le caractère de remplacement « � », car si vous copiez un rectangle ouvert, vous copiez bien le caractère original et son point de code, alors que si vous copiez le caractère de remplacement, vous ne copiez pas le caractère qu’il remplace…

Pour de l’information sur l’affichage de l’UCS/Unicode : http://fr.wikipedia.org/wiki/Aide:Unicode

Annexe : Notation hexadécimale

Binaire (base 2) Décimal (base 10) Hexadécimal (base 16)
0 0 0
1 1 1
10 2 2
11 3 3
100 4 4
101 5 5
110 6 6
111 7 7
1000 8 8
100 4 4
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F
10000 16 10
10001 17 11
10010 18 12

Pourquoi définit-on les points de code en hexadécimal et non en décimal?

Pour la même raison que nous préférons normalement manipuler, en décimal, des chiffres ronds comme 10, 100, 1000, etc.

En effet, alors que le nombre binaire 1,0000,0000,0000,00002 peut être considéré comme un chiffre « rond » pour un ordinateur, il représente 6553610 en décimal… mais 1000016 en hexadécimal.

En bout de ligne, notons que la seule différence d’une base à l’autre, que ce soit 2, 8, 10 ou 16, c’est le nombre de caractères avec lequel on compte :

  • En binaire, on utilise les deux caractères 0 et 1.
  • En décimal, on utilise dix caractères de 0 à 9.
  • En hexadécimal, on utilise seize caractères de 0 à 9 puis de A à F.

Finalement, les avantages de la notation hexadécimale sont :

  1. Concision : F16 = 15
  2. Proximité avec la notation binaire comme on l’a vu ci-haut.
  3. Conversion en binaire beaucoup plus simple qu’à partir de la notation décimale
 

Réf. :

  1. Qu’est ce qu’Unicode? (en français)
  2. Introduction technique à l’Unicode
  3. Glossaire des termes de l’Unicode
  4. Autre introduction en français au standard Unicode
  5. MySQL – Jeux de caractères et collation
  6. Endianness et BOM (Byte Order Mark)
  7. Saut de ligne et Unicode
  8. HTML et Unicode
  9. Unicode Character Search
  10. Équivalence et normalisation Unicode
  11. Caractères « privés » (Private Use Characters) et le logo d’Apple (U+F8FF)
Publicité

Encore des jeux de caractères : ISO 8859-1, MacRoman, CP1252?

Dans la première partie, Jeux de caractères : Morse, ASCII, ISO/CEI 646?, nous avons survolé les origines d’une longue tradition de jeux de caractères aux noms tous plus effrayants les uns que les autres.

Exemple de jeux de caractères dans Chrome

Nous nous sommes attardés à des jeux de caractères sur 7 bits seulement et nous avons vu que la norme ISO/CEI 646 permettait de définir des variantes nationales pour pallier au manque flagrant de caractères tels que les caractères accentués.

Malheureusement, l’ajout d’un bit n’a pas réglé le problème. Avec 8 bits, on peut seulement représenter 256 caractères. Pour cette raison, plusieurs jeux de caractères ont encore été créés et pas seulement par l’ISO… des entreprises tels que Microsoft, Apple et IBM se sont mises de la partie.

L’EBCDIC et les pages de code

Une page de code est tout simplement un synonyme de jeu de caractères et le terme aurait été introduit par IBM avec l’EBCDIC, un encodage de caractères sur 8 bits aussi vieux que l’ASCII et de plus, incompatible avec lui.

Pour bien apprécier le degré d’absurdité de certaines pages de code, il suffit de comparer les variantes nord-américaine (037) et britannique (285) de l’EBCDIC. Elles sont presqu’en tout point semblables à l’exception de quelques caractères seulement. Parmi ceux-ci, à la position hexadécimal 5B, il y a le symbole de dollar « $ » dans l’une et le symbole de la livre sterling « £ » dans l’autre.

Par conséquent, si on prend pour acquis que les nord-américains et les britanniques utilisaient leurs variantes respectives, il est facile d’imaginer que si les américains inscrivaient des montants en dollars dans un document, puis que les britanniques ouvraient le même document, tous les montants s’affichaient en livres sterling…

Conversion radicale des deux devises, mais à la portée de tous. Vous prenez une efface, vous supprimez le symbole de dollar puis vous écrivez le symbole de la livre sterling.

L’ISO/CEI 8859, une extension 8 bits de l’US-ASCII

Le jeu de caractères sur 8 bits de l’ISO, soit l’ISO/CEI 8859, reprend les caractères imprimables de l’US-ASCII en excluant les caractères de contrôle sur les plages 0 à 31. Elle utilise donc le huitième bit, c.-à-d. la plage 128 à 255, pour ajouter de nouveaux caractères. Cependant, pour une raison pas bien claire, la norme n’assigne aucun caractère sur la plage 127 à 159.

L’ISO 8859 a pour but de définir des jeux de caractères basés sur l’alphabet latin. Il existe 16 jeux de caractères ISO 8859, de l’ISO 8859-1 à l’ISO 8859-16, et chaque partie contient les caractères d’une ou plusieurs langues groupées selon la région.

L’ISO/CEI 8859-1 (Latin-1) et les langues d’Europe occidentale

En ce qui nous concerne, l’anglais et le français font partie du premier jeu de caractères, soit l’ISO 8859-1, qui représente les langues d’Europe occidentale. Parmi les langues « d’Europe occidentale », on trouve l’anglais, le français, l’allemand, l’italien, l’espagnol, l’islandais, le danois, etc.

Pour ces langues, les grands systèmes d’exploitation avaient aussi leur propre jeux de caractère, plus ou moins équivalents. Sous Windows, c’est la page de code 1252 (CP-1252), sous Mac, c’est le Mac Roman et sous DOS, c’est la page de code 437. Tous ces jeux de caractères ont au moins la décence d’être compatible avec l’ASCII.

« Ÿ » est un caractère français?

L’ISO 8859-1 ne contient pas tous les caractères français, car il n’inclut pas les caractères « œ », « Œ » et « Ÿ » – ce dernier étant apparemment utilisé dans certains noms propres tels que Moÿ-de-l’Aisne et Faÿ-lès-Nemours. En fait, le caractère minuscule « ÿ » existe dans la norme, mais pas la lettre majuscule, qui est nécessaire si on veut écrire ces noms en lettres majuscules.

Pour cette raison, l’ISO 8859-15, aussi connu sous Latin-9 (%$#!???), a éventuellement été créé pour ajouter des caractères manquants en échange de quelques autres moins populaires.

Différences entre l’ISO 8859-1 et l’ISO 8859-15
Position décimale 164 166 168 180 184 188 189 190
ISO 8859-1 ¤ ¦ ¨ ´ ¸ ¼ ½ ¾
ISO 8859-15 Š š Ž ž Œ œ Ÿ

Malgré cette mise à jour, l’ISO 8859-1 est toujours resté la variante prédominante – en effet, personnellement, je n’utilise pas beaucoup le « Ÿ »…

Dernière remarque concernant l’ISO 8859-1 : retenons que l’ISO 8859-1 n’est pas le même chose que l’ISO-8859-1 (il y a un tiret supplémentaire %$#?!!!). En plus du tiret supplémentaire, l’ISO-8859-1 inclut des caractères de contrôles aux positions inutilisées de la version originale. Ne me demandez pas pourquoi…

Windows-1252 (malheureusement appelé ANSI à l’occasion)

Cette page de code est celle qui vient encore aujourd’hui avec Windows dans les langues « d’Europe occidentale » selon la classification ISO. Son succès repose sur le fait qu’elle est non seulement une extension d’ASCII, mais une extension de l’ISO 8859-1.

Souvenons-nous que dans l’ISO 8859-1, la plage 128 à 159 est inutilisée et que dans l’ISO-8859-1, elle contient des caractères de contrôle. Le Windows-1252 a utilisé cette plage pour y insérer les caractères manquants en français (Œ, œ, Ÿ) et en finnois (Š, š, Ž, ž) ainsi que d’autres caractères tels que le symbole de l’Euro « € ». Cette fois-ci, Microsoft a fait ce que l’ISO aurait dû faire au point de départ selon moi.

Ainsi, il contient tous les caractères qui ont été ajoutés avec l’ISO 8859-15 tout en restant compatible avec l’ISO 8859-1, ce qui n’est pas vrai avec l’ISO 8859-15… Grâce à cette compatibilité et à la popularité de Windows, les navigateurs, jusqu’à ce jour, affichent carrément l’ISO-8859-1 en Windows-1252.

MacRoman

Bien que Mac OS utilise l’UTF-8 depuis Mac OS X, il utilisait auparavant le MacRoman, compatible avec l’ASCII, mais sans plus. Il contient la grande majorité des caractères de l’ISO 8859-1 mais dans un ordre complètement différent. Par contre, il n’y a pas de plage inutilisée, ainsi il peut représenter plus de caractères que l’ISO 8859-1.

Le MacRoman contient les caractères français « Œ », « œ » et « Ÿ » mais non les caractères finnois « Š », « š », « Ž » et « ž ». Il n’encode pas non plus les caractères islandais « ð », « Ð », « þ », « Þ », « ý » et « Ý ».

Pour les Islandais, il y avait le MacIceland!

Et maintenant?

Ensuite, il y a l’unicode et spécialement l’UTF-8. L’unicode est un nouveau chapitre qui vise enfin à unifier la représentation de tous les caractères dans une même norme. Et pour une fois, la norme porte bien son nom.

Voyons maintenant si j’aurai le courage de perpétuer cette litanie du diable sur les horreurs du passé, du présent et du futur, en parlant de l’unicode…

Mais si vous me connaissez déjà, vous savez que ma curiosité est plus forte que l’ennui.

Réf. :

  1. Introduction aux jeux de caractères

Jeux de caractères : Morse, ASCII, ISO/CEI 646?

À bien des égards, les jeux de caractères trônent bien près du sommet de la pyramide de l’horreur. Tout le monde a vu, un jour ou l’autre, un caractère ind�sirable dans un courriel ou sur une page web à cause d’un problème d’encodage de caractères.

Bien que ces problèmes aient été autrement plus pénible à une certaine époque, je ne peux m’empêcher de ressentir, en tant que mortel, un serrement à l’estomac à chaque fois que j’en entends parler. À force de voir des Latin1, ISO-8859-1, CP-1252, ANSI, ISO/CEI 8859-15, US-ASCII, UTF-8 et UTF-16BE, le temps est venu de mettre un peu d’ordre dans ce ß°®}$%?#&*~{!

Qu’est-ce que l’encodage de caractères? Qu’est-ce qu’on a fait pour mériter ça?

Pour un signal électrique, un disque magnétique ou une onde électromagnétique, un caractère ne signifie rien. Afin de transmettre un caractère ou de le stocker sur un support numérique, il faut le convertir en quelque chose de plus simple. Par exemple, le code morse : chaque caractère est converti en une séquence d’impulsions courtes ou longues. Ainsi, avec un seul son, tantôt court, tantôt long, on pourrait communiquer un roman en entier, puis à la fin du processus, halluciner des bips des jours durant.

Jeux de caractères Caractères
En décimal (et hexadécimal)
a é
ASCII 97 (61) Inexistant
MacRoman 97 (61) 142 (8E)
ISO 8859-1 97 (61) 233 (E9)
UTF-8 97 (61) 195 169 (C3A9)
deux octets

En informatique, il n’y a pas de bips mais des bits. Le bit a deux valeurs possibles : 1 ou 0. Par conséquent, il faut une façon d’encoder les caractères en 1 et en 0, ou autrement dit, de les encoder en binaire.

Entrent en scène les jeux de caractères : chacun d’entre eux représente une façon d’encoder les caractères en binaire. C’est tout simplement une table de correspondance entre chaque caractère et sa valeur binaire. Par exemple, en ASCII, le caractère ‘a’ correspond à 01100001.

Pour des raisons évidentes de concision, nous utiliserons les nombres décimaux plutôt que les nombres binaires ou hexadécimaux – oui, je sais, c’est la pénible ascension de l’Affreux. En décimal, 01100001 est égal à 97.

Comme on peut le voir dans le tableau ci-dessus, le caractère ‘a’ correspond à 97 dans la plupart des jeux de caractères. Par contre, le caractère ‘é’ change dans chaque jeu de caractères…

Qu’est-ce qu’un problème d’encodage? C’est pourtant juste des foutus caractères, non?

Quand un logiciel manipule un fichier texte, il doit savoir dans quel jeu de caractères l’interpréter.

Prenons un logiciel A utilisant l’ISO 8859-1 et un logiciel B utilisant l’UTF-8 :

  • Le logiciel A écrit le caractère ‘é’ (en ISO 8859-1) dans un fichier et le sauvegarde.
  • Donc, le fichier contient le nombre 233.
  • Le logiciel B ouvre le fichier et interprète le nombre 233 (en UTF-8).
  • Puisque le nombre 233 ne représente pas un caractère en UTF-8, il affiche ‘�’.

Notons que le problème ne se poserait pas si le caractère était ‘a’, car l’ISO 8859-1 et l’UTF-8 encodent le caractère ‘a’ de la même manière, soit le nombre 97. C’est parce qu’ils sont compatibles au jeu de caractères ASCII.

Et je vous jure que l’ASCII, c’est certainement le truc le plus intéressant après le 120 volts…

ASCII (sur 7 bits)

L’ASCII a été développé aux États-Unis au début des années 60 pour les téléscripteurs. Les 7 bits de l’ASCII permettent seulement d’encoder 128 caractères (de 0 à 127).

Les 95 caractères ASCII affichables.

Les 95 caractères ASCII affichables.

L’ASCII contient 95 caractères affichables (sur la plage 32 à 126) et 33 caractères de contrôle (de 0 à 31 et le 127). Parmi ces derniers, on compte l’espace (SP), le saut de ligne (LF), le retour de chariot (CR), la touche « Escape » (ESC), etc.

N’oublions pas que l’ASCII a été conçu pour les télécommunications préhistoriques, donc on trouve des caractères tels que la fin de transmission (EOT), l’accusé de réception (ACK) et l’annulation (CAN) – en effet, il fut une époque déroutante où les protocoles de communication et les jeux de caractères ne faisaient qu’un!

Par contre, l’ASCII reste un standard américain. Entre autres, il ne contient aucun caractère accentué… Ainsi, pour éviter la prolifération chaotique des jeux de caractères en fonction des besoins de chaque langue et pour assurer une certaine compatibilité, l’ISO a créé l’ISO/CEI 646 – qui personnellement, me laisse encore aujourd’hui un goût particulièrement amer dans la bouche…

ISO/CEI 646 (sur 7 bits)

Le principal problème de l’ISO/CEI 646 reste qu’il utilise, tout comme l’ASCII, seulement 7 bits. Il est donc limité à 128 caractères. Bien que ce soit plus de caractères qu’il n’en faut pour écrire des SMS (lol), ces 7 bits sont nettement insuffisants pour représenter tous les caractères. Alors, l’ISO/CEI 646 a défini un jeu de caractères presqu’en tout point équivalent à l’ASCII sauf que la norme permet de remplacer certains caractères pour créer des variantes nationales.

Voici les 12 caractères variants de l’ISO/CEI 646 par rapport à l’ASCII : # $ @ [ \ ] ^ ` { | } ~

Avec cette avancée – quelque peu douteuse -, l’ASCII est devenu la variante américaine de l’ISO/CEI 646 (ISO-646-US ou US-ASCII) puis d’autres variantes sont apparues. Entre autres, soulignons qu’il existait une variante canadienne dans laquelle des caractères tels que @, [, et ] étaient remplacés par à, â et ê pour que l’on puisse écrire en français et enfin assouvir nos pulsions obesessionnelles et compulsives.

Enfin, avec l’avènement des jeux de caractères sur 8 bits, l’ISO/CEI 646 est tout simplement tombé en désuétude, pour céder la place à une nouvelle génération d’absurdités…

Suite : Encore des jeux de caractères : ISO 8859-1, MacRoman, CP1252?