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 :
- 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.
- 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.
- 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 :
- Concision : F16 = 15
- Proximité avec la notation binaire comme on l’a vu ci-haut.
- Conversion en binaire beaucoup plus simple qu’à partir de la notation décimale
Réf. :
- Qu’est ce qu’Unicode? (en français)
- Introduction technique à l’Unicode
- Glossaire des termes de l’Unicode
- Autre introduction en français au standard Unicode
- MySQL – Jeux de caractères et collation
- Endianness et BOM (Byte Order Mark)
- Saut de ligne et Unicode
- HTML et Unicode
- Unicode Character Search
- Équivalence et normalisation Unicode
- Caractères « privés » (Private Use Characters) et le logo d’Apple (U+F8FF)
Merci pour le partage du du protocole ISO/CEI 10646 et Unicode.