Unicode
Unicode |
---|
Jeux de caractères |
Équivalences normalisées |
Propriétés et algorithmes
|
Codage |
Autres transformations |
Applications d'échanges de données |
Unicode est une norme informatique, développée par le Consortium Unicode, qui vise à donner à tout caractère de n’importe quel système d’écriture un nom et un identifiant numérique, et ce de manière unifiée, quelle que soit la plate-forme informatique ou le logiciel.
Totalement compatible avec le jeu de caractères universel UCS, la norme Unicode l'étend en lui ajoutant un modèle de représentation et de traitement de textes complets, en conférant à chaque caractère un jeu de propriétés normalisées ou informatives, en décrivant avec précision les relations sémantiques qui peuvent exister entre plusieurs caractères successifs d’un texte, et en normalisant des algorithmes de traitement qui préservent au maximum la sémantique des textes transformés, tout en étendant l’interopérabilité de la représentation de ces textes sur des systèmes hétérogènes.
En pratique, la norme Unicode inclut intégralement la norme ISO/CEI 10646 en tant que sous-ensemble, puisque cette dernière ne normalise que les caractères individuels en leur assignant un nom et un numéro normatif et une description informative très limitée, mais aucun traitement ni aucune spécification ou recommandation pour leur emploi dans l’écriture de langues réelles, ce que seule la norme Unicode définit précisément. Toutefois, la norme ISO/CEI 10646 confère à Unicode le statut de norme internationale approuvée pour le codage des textes ; Unicode est également une norme de facto pour le traitement de ces textes, et sert en 2009 de base à de nombreuses autres normes.
[modifier] But
Unicode, dont la première publication remonte à 1991, a été développée dans le but de remplacer l’utilisation de pages de code nationales.
Ces pages de code présentaient en effet quelques problèmes. Par exemple lorsqu’était prévu un caractère « signe monétaire », le même texte autorisant aux États-Unis une dépense en dollars pouvait une fois transmis par courrier électronique au Royaume-Uni autoriser la même dépense en livres sterling, sans que quoi que ce soit ait été modifié au texte.
Dans la pratique, tous les systèmes d’écriture ne sont pas encore présents, car un travail de recherche documentaire auprès de spécialistes peut encore s’avérer nécessaire pour des caractères rares ou des systèmes peu connus (parce que disparus, par exemple).
Cependant, les systèmes les plus utilisés dans le monde sont représentés, ainsi que des règles sur la sémantique des caractères, leurs compositions et la manière de combiner ces différents systèmes. — Par exemple, comment insérer un système d’écriture de droite à gauche dans un système d’écriture de gauche à droite (Texte bi-directionnel).
[modifier] Normes et versions
Le travail sur Unicode est parallèle et synchronisé avec celui sur la norme ISO/CEI 10646 dont les buts sont les mêmes. L’ISO/CEI 10646, une norme internationale publiée en français et en anglais, ne précise cependant ni les règles de composition de caractères, ni les propriétés sémantiques des caractères.
Unicode aborde cependant la problématique de la casse, du classement alphabétique, et de la combinaison d’accents et de caractères. Depuis la version 1.1 d’Unicode et dans toutes les versions suivantes, les caractères ont les mêmes identifiants que ceux de la norme ISO/CEI 10646 : les répertoires sont maintenus parallèlement, à l’identique lors de leur normalisation définitive, les deux normes étant mises à jour simultanément. Les deux normes Unicode (depuis la version 1.1) et ISO/CEI 10646 assurent une compatibilité ascendante totale : tout texte conforme à une version antérieure doit rester conforme dans les versions ultérieures.
Ainsi les caractères de la version 3.0 d’Unicode sont ceux de la norme ISO/CEI 10646:2000. La version 3.2 d’Unicode classait 95 221 caractères, symboles et directives.
La version 4.1 d’Unicode, mise à jour en novembre 2005, contient :
- 137 468 caractères à usage privé (assignés dans toutes les versions d’Unicode et suffisants pour tous les usages) ;
- plus de 97 755 lettres ou syllabes, chiffres ou nombres, symboles divers, signes diacritiques et signes de ponctuation, avec parmi eux :
- plus de 70 207 caractères idéographiques, et
- parmi eux, 11 172 syllabes hangûles précomposées ; ainsi que
- plus de 70 207 caractères idéographiques, et
- 8 258 points de codes réservés de façon permanente interdits pour le codage de texte (assignés dans toutes les versions d’Unicode) ; et
- plusieurs centaines de caractères de contrôle ou modificateurs spéciaux ;
soit un total de près de 245 000 points de codes assignés dans un espace pouvant contenir 1 114 112 codes différents.
Quelques problèmes semblent cependant exister, pour le codage des caractères chinois, à cause de l’unification des jeux idéographiques utilisés dans différentes langues, avec une calligraphie légèrement différente et parfois signifiante, mais ils sont en cours de résolution par Unicode qui a défini des sélecteurs de variantes et ouvert un registre de séquences normalisées qui les utilise.
La version 5.0 a été publiée en juillet 2006 et la version 5.2 en octobre 2009.
[modifier] Les couches d’Unicode
Unicode est défini suivant un modèle en couches (Note technique Unicode #17). Les autres normes ne faisaient typiquement pas de distinction entre le jeu de caractères et la représentation physique. Les couches sont ici présentées en partant de la plus haute (la plus éloignée de la machine).
[modifier] Répertoire des caractères abstraits (Abstract Character Repertoire)
La couche la plus élevée est la définition du jeu de caractères. Par exemple, Latin-1 a un jeu de 256 caractères et Unicode normalise actuellement plus de 120 000 caractères. En outre, Unicode leur donne des noms. Dresser la liste des caractères et leur donner des noms est donc la première couche d’Unicode.
Par exemple, le caractère Ç est nommé "Lettre majuscule latine c cédille".
Cette définition est totalement identique à celle de l’ISO/CEI 10646, qui approuve toute extension du répertoire. Unicode ne reprend dans le texte de sa norme que les noms normatifs en anglais, mais la norme ISO/CEI 10646 est publiée en deux langues également normatives. Aussi les noms en anglais et en français sont tous deux normalisés.
Dans les faits, toute extension du répertoire se fait aujourd’hui conjointement entre le Groupe de travail WG2 de l’ISO/CEI 10646 (dont les membres votants sont uniquement des autorités de normalisation nationales de tous les pays du monde, ou leur représentant officiel), et le Comité technique Unicode UTC (dont les membres votants peuvent être n’importe quelle organisation privée ou d’intérêt public, ou même un gouvernement, qui a adhéré et paye une redevance annuelle leur permettant de participer à ces décisions).
[modifier] Jeu de caractères codés (Coded Character Set)
Ici, on ajoute à la table précédente un index numérique. Notons bien qu’il ne s’agit pas d’une représentation en mémoire, juste d’un nombre.
Ce nombre, le point de code, est noté U+xxxx où xxxx est en hexadécimal, et comporte 4 chiffres pour tous les points de codage du premier plan de base multilingue (donc entre U+0000 et U+FFFF), 5 chiffres pour les 15 plans suivants (entre U+10000 et U+FFFFF), ou 6 chiffres pour le dernier plan (entre U+100000 et U+10FFFF).
Ainsi, le caractère nommé "Lettre majuscule latine c cédille" a un index de U+00C7.
Tous les points de code entre U+0000 et U+10FFFF sont valides, même si certains sont réservés et non encore assignés à des caractères, ou si certains points de code sont assignés à des non-caractères (par exemple U+FFFE ou U+FFFF) dont l’usage est interdit dans un texte, ou sont réservés pour permettre le codage de n’importe quel texte conforme avec une des formes de transformation standard Unicode (voir UTF-16, plus bas).
On notera également qu’Unicode (ou ISO/CEI 10646) a assigné de nombreux points de code à des caractères valides mais dont la sémantique est inconnue car d’usage privé (par exemple les deux derniers plans entre U+F0000 et U+10FFFF sont entièrement dédiés à cet usage, hormis les deux points de code à la fin de chaque plan qui sont des non-caractères interdits dans un texte conforme).
Là encore, la normalisation du codage, c’est-à-dire l’assignation des points de codes aux caractères du répertoire commun est une décision conjointe partagée entre les normes Unicode et ISO/CEI 10646. Tous les caractères du répertoire disposent d’un point de code unique (même si pour certaines langues ou pour Unicode certains caractères sont considérés comme équivalents).
On peut noter que si le répertoire des caractères est extensible, il ne l’est que dans les limites permises par le codage des points de code assignables aux caractères codés. Une grande majorité des points de code possibles n’est pas assignée à un caractère particulier, mais peut le devenir à tout moment.
Aussi ces points de code encore libres ne sont pas considérés comme invalides mais représentent bien des caractères abstraits (non encore spécifiés, et temporairement réservés). Ces caractères abstraits (de même que les caractères à usage privé) complètent le jeu de caractères codés du répertoire normalisé pour former un jeu unique dit « jeu de caractères codés universel » (Universal Coded Character Set, souvent abrégé en UCS) qui contient tous les jeux de caractères codés des répertoires de chacune des versions passées, présentes et futures de l’ISO/CEI 10646 et d’Unicode (depuis la version 1.1 uniquement).
[modifier] Formalisme de codage des caractères (Character Encoding Form)
Cette fois, nous arrivons à une représentation physique (en mémoire, sur disque, etc.) : cette couche spécifie quelles unités de stockage (code units), octets ou bien mots de 16 - seizets - ou de 32 bits, vont représenter un caractère ou plus exactement un point de code.
[modifier] Mécanisme de sérialisation des caractères (Character Encoding Scheme)
Cette couche s’occupe de sérialiser les unités de stockage définies par la couche du dessus. C’est ici que se traite l’opposition entre gros boutiens (octet le plus significatif d’abord) et petits boutiens (octet le moins significatif d’abord).
C’est également ici qu’on spécifie la marque de boutianité (BOM, pour Byte Order Mark) qui permet d’indiquer en début de fichier s’il est en gros boutien ou en petit boutien. Dans le monde Internet, on l’utilise rarement, en préférant un marquage explicite (“charset=UTF-16BE” en MIME, par exemple, pour indiquer un flot de données gros boutien, où BE signifie Big Endian).
[modifier] Surcodage de transfert (Transfer Encoding Syntax)
Ici, interviennent optionnellement les mécanismes de compression ou de chiffrement.
Il peut aussi y avoir un surcodage comme pour le LDAP qui spécifie que les chaînes Unicode doivent être codées en UTF-8 et surcodées en Base64.
[modifier] La limite de l’octet
Contrairement aux normes précédentes, Unicode sépare la définition du jeu de caractères (la liste des caractères, leur nom et leur index, le point de code) de celle du codage. Ainsi, on ne peut donc pas parler de la taille d’un caractère Unicode, car elle dépend du codage choisi.
Là où l’ASCII utilisait jadis 7 bits et ISO 8859-1 8 bits (comme la plupart des pages de codes nationales), Unicode, qui rassemble les caractères de chaque page de code, avait besoin d’utiliser plus que les 8 bits d’un octet. La limite fut dans un premier temps fixée à 16 bits pour les premières versions d’Unicode, et à 32 bits pour les premières versions de la norme ISO/CEI 10646.
La limite actuelle est désormais placée entre 20 et 21 bits par point de code assigné aux caractères normalisés dans les deux normes, désormais mutuellement compatibles :
- Le groupe de travail international de l’ISO normalise l’assignation des points de code aux caractères, leur nom officiel et réserve les blocs de points de code utilisés par chaque écriture ou groupe d’écritures. Il documente aussi une représentation graphique possible (indicative) pour chaque caractère (cette représentation graphique étant si possible non ambiguë grâce au placement des caractères normalisés dans les blocs de code appropriés pour un nombre limité d’écritures).
- Le groupe de travail du Consortium Unicode normalise plus précisément (dans la norme Unicode) leur sémantique pour les traitements automatisés grâce aux tables de propriétés des caractères, et la mise au point d’algorithmes standards utilisant ces propriétés.
- Les deux organismes de normalisation collaborent pour synchroniser en permanence leur répertoire normalisé dans des versions officielles référencées mutuellement, et travaillent ensemble pour les amendements (les versions ne devenant officielles qu’une fois que les deux organismes ont chacun approuvé et complètement défini les additions de nouveaux caractères).
- En pratique, pour la plupart des développeurs d’applications, la norme ISO 10646 apparaît comme un sous-ensemble de la norme Unicode plus complète, mais elle dispose des mêmes points de code pour exactement le même jeu de caractères que ceux de la norme Unicode (c’est pourquoi la norme Unicode est plus connue car plus appropriée pour les traitements informatisés, mais aussi la norme Unicode est plus accessible car consultable gratuitement sur Internet).
[modifier] UTF, Universal Transformation Format
Unicode et ISO/CEI 10646 acceptent plusieurs formes de transformation universelle pour représenter un point de code valide. Citons :
Le nombre après UTF représente le nombre minimal de bits des codets avec lesquels un point de code valide est représenté.
Ces transformations ont été initialement créées pour la représentation interne et les schémas de codage des points de code de la norme ISO 10646, qui au départ pouvait définir des points de code sur 31 bits. Depuis, la norme ISO/CEI10646 a été amendée, afin que les trois formes soient totalement compatibles entre elles et permettent de coder tous les points de code (car UTF-16 ne permet de représenter que les points de code des 17 premiers plans).
Unicode a normalisé également de façon très stricte ces trois formes de transformation de tous les points de code valides (U+0000 à U+D7FF et U+E000 à U+10FFFF) et uniquement eux, que ce soit pour représenter du texte sous forme de suites de points de codes, ou des points de code assignés aux caractères valides, ou réservés, ou assignés à des non-caractères. Les points de code assignés aux demi-zones (U+D800 à U+DFFF), utilisés uniquement en UTF-16, sont invalides isolément puisqu’il servent à la représentation, par un couple de 2 codets de 16 bits, des points de code des 16 plans supplémentaires.
[modifier] UTF-8
L’UTF-8, spécifié dans le RFC 3629, est le plus commun pour les applications Unix et Internet. Son codage de taille variable lui permet d’être en moyenne moins coûteux en occupation mémoire. Mais cela ralentit nettement les opérations où interviennent des extractions de sous-chaînes, car il faut compter les caractères depuis le début de la chaîne pour savoir où se trouve le premier caractère à extraire.
L’UTF-8 assure aussi, et c’est son principal avantage, une compatibilité avec les manipulations simples de chaînes en ASCII dans les langages de programmation. Ainsi, les programmes écrits en C peuvent souvent fonctionner sans modification.
Initialement, l’UTF-8 pouvait coder n’importe quel point de code entre U+0000 et U+7FFFFFFF (donc jusqu’à 31 bits). Cet usage est obsolète et la norme ISO/CEI 10646 a été amendée pour ne plus supporter que les points de code valides des 17 premiers plans, sauf ceux de la demi-zone correspondant aux codets utilisés en UTF-16 pour la représentation sur deux codets des points de code des 16 plans supplémentaires. Aussi les séquences les plus longues en UTF-8 nécessitent au maximum 4 octets, au lieu de 6 précédemment. De plus, UTF-8 a été amendé d’abord par Unicode puis par l’ISO/CEI10646 pour ne plus accepter que la représentation la plus courte de chaque point de code (unicité du codage).
Son avantage sur l’UTF-16 (et l'UTF-32) est que les différences d'ordonnancement des octets composant un mot (endianness) ne posent pas de problème dans un réseau de systèmes hétérogènes ; ainsi, cette transformation est utilisée aujourd'hui par la plupart des protocoles d’échange normalisés.
D’autre part, l’UTF-8 est totalement compatible pour la transmission de textes par des protocoles basés sur le jeu de caractères ASCII, ou peut être rendu compatible (au prix d’une transformation sur plusieurs octets des caractères non-ASCII) avec les protocoles d’échange supportant les jeux de caractères codés sur 8 bits (qu’ils soient basés sur ISO-8859 ou de nombreux autres jeux de caractères codés sur 8 bits définis par des normes nationales ou des systèmes propriétaires particuliers).
Son principal défaut est le codage de longueur très variable (1 octet pour les points de code assignés aux caractères ASCII/ISO646, 2 à 4 octets pour les autres points de code), même si l'auto-synchronisation propre à l'encodage UTF-8 permet de déterminer le début d'une séquence à partir d’une position aléatoire (en effectuant au plus 3 lectures supplémentaires des codets qui précèdent). Cependant, cet encodage n'est pas conçu pour faciliter le traitement des chaînes de caractères, à cet usage on lui préfère souvent l’UTF-16, parfois l’UTF-32 (gourmand en mémoire).
[modifier] Dérivés
- Certains programmes (par exemple, la base de données Oracle) représentant en interne leurs données Unicode au format UTF-16 ont (ou ont connu) un défaut de conversion vers UTF-8 : un caractère compris entre U+10000 et U+10FFFF, stocké sur deux mots de 16 bits, se retrouve converti en UTF-8 comme étant une suite de deux caractères Unicode. Cela a amené la création « accidentelle » du CESU-8 et a pour avantage de faciliter l'implémentation d'Unicode sur des plates-formes 16 bits.
- Le caractère Unicode nul U+0000 est codé en UTF-8 sous forme d’un unique octet nul 0x00. Selon le standard Unicode, ce caractère n'a aucune signification particulière[1] ; toutefois (pour des raisons conceptuelles historiques), les bibliothèques de traitement de chaînes du langage C considèrent ce caractère de contrôle comme une fin de chaîne, ce qui complique l'implémentation de certains cas d'application. Sous la plate-forme Java, la version « (en)Modified UTF-8 » est née en reprenant l'avantage de la portabilité « 16 bits » du CESU-8 et en y ajoutant la possibilité d'encoder U+0000 sous la séquence 0xC0 0x80 (normalement interdite en UTF-8[2]) : en échangeant de la sorte avec les bibliothèques C natives de la plateforme supportée, la plate-forme peut gérer facilement tous les textes Unicode valides ainsi que les fichiers de classes compilées (format alternatif portable, indépendant de l'endianness et de la taille des mots).
[modifier] UTF-16
L’UTF-16 est un bon compromis lorsque la place mémoire n’est pas trop restreinte, car la grande majorité des caractères Unicode assignés pour les écritures des langues modernes (dont les caractères les plus fréquemment utilisés) le sont dans le plan multilingue de base et peuvent donc être représentés sur 16 bits. L’ISO/CEI 10646 nomme ces entités de 16 bits des seizets.
Toutefois les points de code des 16 plans supplémentaires nécessitent une transformation sur deux seizets :
- le premier seizet pris dans la demi-zone haute (0xD800 à 0xDBFF) permet de représenter les 10 bits de poids fort de la différence entre le point de code supplémentaire et le premier point de code hors du plan multilingue de base ;
- le second seizet pris dans la demi-zone basse (0xDC00 à 0xDFFF) permet de représenter les 10 bits de poids faible du point de code supplémentaire.
Il est possible de déterminer le début de la séquence de codage à partir d’un point quelconque d’un texte représenté en UTF-16 en effectuant au maximum une lecture supplémentaire, uniquement si ce codet est dans la demi-zone basse. Cette forme est plus économique et plus facile à traiter rapidement que l’UTF-8 pour la représentation de textes contenant peu de caractères ASCII (U+0000 à U+007F).
Toutefois, cette transformation possède deux schémas de codage incompatibles qui dépendent de l’ordonnancement des octets dans la représentation d’entiers sur 16 bits. Pour résoudre cette ambiguïté et permettre la transmission entre systèmes hétérogènes, il est nécessaire d’adjoindre une information indiquant le schéma de codage utilisé (UTF-16BE ou UTF-16LE), ou bien de préfixer le texte codé avec la représentation du point de code valide U+FEFF (assigné au caractère « espace insécable de largeur nulle », un caractère aujourd’hui réservé à ce seul usage en tant que marqueur d’ordonnancement des octets), puisque le point de code “renversé” U+FFFE valide est un non-caractère, interdit dans les textes conformes à Unicode et ISO/CEI10646.
L’autre défaut d’UTF-16 est qu’un texte transformé avec lui et transmis avec l’un ou l’autre des deux schémas de codage contient un grand nombre d’octets nuls ou ayant une valeur en conflit avec les valeurs d’octets réservées par certains protocoles d’échange.
C’est notamment le codage qu’utilise la plate-forme Java en interne, ainsi que Windows pour ses APIs compatibles Unicode (avec le type "WCHAR").
[modifier] UTF-32
L’UTF-32 est utilisé lorsque la place mémoire n’est pas un problème et que l’on a besoin d’avoir accès à des caractères de manière directe et sans changement de taille (hiéroglyphes).
L’avantage de cette transformation normalisée est que tous les codets ont la même taille. Il n’est donc pas nécessaire de lire des codets supplémentaires pour déterminer le début de la représentation d’un point de code.
Toutefois, ce format est particulièrement peu économique (y compris en mémoire) puisqu’il « gaspille » inutilement au moins un octet (toujours nul) par caractère. La taille en mémoire d’un texte joue négativement sur les performances puisque cela nécessite plus de lectures et écritures sur disque en cas de saturation de la mémoire physique, et que cela diminue aussi les performances du cache mémoire des processeurs.
Pour les textes écrits dans les langues modernes actuelles (hormis certains caractères rares du plan idéographique supplémentaire), et n’utilisant donc que les points de code du plan multilingue de base, cette transformation double la quantité mémoire nécessaire par rapport à l’UTF-16.
Comme l’UTF-16, l’UTF-32 possède plusieurs schémas de codage dépendant de l’ordonnancement des octets composant un entier de plus de 8 bits (deux schémas de codage de l’UTF-32 sont normalisés, UTF-32BE et UTF-32LE). Il est donc aussi nécessaire de préciser ce schéma de codage, ou de le déterminer en préfixant le texte par la représentation en UTF-32 du point de code U+FEFF. Comme l’UTF-16, la présence d’octets nuls dans les schémas de codage normalisés de l’UTF-32 le rend incompatible avec de nombreux protocoles d’échange entre systèmes hétérogènes.
Aussi ce format n’est utilisé le plus souvent que très localement pour certains traitements en tant que forme intermédiaire plus facile à manipuler, et on lui préfère souvent la transformation UTF-16 souvent plus performante pour traiter et stocker des quantités importantes de textes, la conversion entre les deux étant très simple à réaliser, et très peu coûteuse en termes de complexité de traitement.
En fait, de très nombreuses bibliothèques de traitement de textes sont écrites uniquement avec l’UTF-16 et sont plus performantes qu’en UTF-32, même lorsque les textes contiennent des caractères des plans supplémentaires (car ce cas de figure reste rare dans la très grande majorité des cas).
On notera toutefois que la transformation en UTF-32 utilise des codets sur 32 bits, dont de très nombreuses valeurs peuvent ne représenter aucun point de code valide (valeurs hors des deux intervalles représentant les points de code valides U+0000 à U+D7FF et U+E000 à U+10FFFF), donc aucun caractère valide ou réservé (toute information qui y serait contenue ne peut donc pas être du texte au sens d’Unicode). La transmission de textes utilisant ces valeurs invalides de codets dans un des schémas de codage normalisés de l’UTF-32 est interdite pour tout système conforme à Unicode (il faut utiliser plutôt les points de code à usage privé), puisqu’il sera impossible de les représenter dans une autre transformation UTF avec lesquelles les trois UTF normalisées sont bijectivement compatibles.
[modifier] GB18030
Il s’agit d’une transformation de l’Unicode qui n’est pas défini par le Consortium Unicode, mais par l’administration de normalisation en Chine, où son support est obligatoire dans les applications. Historiquement c’était un jeu de caractères codé, qui a été étendu pour supporter l’intégralité du répertoire UCS par une transformation algorithmique complétant une large table de mappage d’un code à l’autre.
[modifier] Les polices de caractères Unicode
Affirmer qu’Unicode code des caractères revient à affirmer qu’il attribue un numéro à des symboles abstraits, selon un principe de codage logique. Unicode ne code en revanche pas les représentations graphiques des caractères, les glyphes. Il n’y a donc pas une bijection entre la représentation du caractère et son numéro, puisque toutes les variantes graphiques de style sont unifiées.
De plus, contrairement à une police ASCII ou latin-1 classique, la sélection d’un glyphe par un code n’est pas unique et est souvent contextuelle, et peut aussi afficher le même glyphe pour des codes différents. Ainsi, le caractère français « é » peut-il être décrit de deux manières : soit en utilisant directement le numéro correspondant au « é », soit en faisant suivre le numéro du « e » par celui de l’accent aigu sans chasse. Quelle que soit l’option choisie, le même glyphe sera affiché. On dira du premier caractère qu’il est précomposé, du second que c’est une composition (deux caractères forment un seul glyphe composé des deux). Ceci est autorisé et même hautement recommandé car les différentes formes de codage sont classées par Unicode comme « canoniquement équivalentes », ce qui signifie que deux formes de codage équivalentes devraient être traitées de façon identique.
De nombreux caractères composites sont dans ce cas et peuvent être codés de ces deux manières (ou plus, certains caractères composés pouvant être décomposés de plusieurs façons, notamment quand ils comportent plusieurs signes diacritiques). Le plus souvent, le caractère précomposé est préférable pour le codage du texte, si celui-ci existe (c’est le cas pour le grec polytonique, par exemple, lequel, codé en décomposition, peut ne pas être satisfaisant graphiquement : selon les polices de caractères, les différents constituants du glyphe étant parfois mal disposés et peu lisibles). Toutefois, tous les caractères composites ne disposent pas d’un point de code unique pour leur forme précomposée.
De même, certains systèmes d’écriture, comme la devânagarî ou les caractères arabes, nécessitent un traitement complexe des ligatures : les graphèmes changent en effet de forme en fonction de leur position et/ou par rapport à leurs voisines (voir Variante contextuelle et Lettre conjointe). La sélection du glyphe correct à utiliser nécessite un traitement permettant de déterminer la forme contextuelle à sélectionner dans la police, alors même que toutes les formes contextuelles sont codées de façon identique en Unicode.
Pour ces raisons, la police Unicode doit être utilisée très prudemment. Avoir une police qui représente un certain nombre ou toutes les représentations graphiques que l’on peut obtenir avec Unicode n’est pas suffisant, il faut en plus que le système d’affichage possède les mécanismes de représentation idoines (le moteur de rendu) capable de gérer les ligatures, variantes contextuelles et formes conjointes de certaines écritures. Au contraire, une police qui ne représente que certains caractères mais qui sait comment les afficher mérite mieux le terme de « police Unicode ». Enfin, il existe des contraintes techniques dans les formats de polices de caractère, qui les empêche de supporter la totalité du répertoire et, en pratique, il est en 2009 impossible de trouver une police de caractères unique supportant tout le répertoire.
Une police de caractères Unicode est donc seulement une police permettant d’afficher directement un texte codé selon toutes les formes autorisées par Unicode, et permettant de supporter un sous-ensemble cohérent adapté à une ou plusieurs langues pour supporter une ou plusieurs écritures. Aucune police de caractère Unicode ne peut « fonctionner » seule, et le support complet de l’écriture nécessite un support de celles-ci dans un moteur de rendu, capable de détecter les formes de codage équivalentes, rechercher les formes contextuelles dans le texte et sélectionner les différents glyphes d’une police codée avec Unicode, en s’aidant au besoin de tables de correspondances incluses dans la police elle-même.
[modifier] Détails techniques
[modifier] Bibliothèques logicielles
La bibliothèque multi plate-forme ICU permet de manipuler des données unicodées. Un support d’Unicode spécifique à certaines plates-formes (non compatible quant au code-source) est également fourni par les systèmes modernes (Java, MFC, GNU/Linux).
Les types à utiliser pour stocker des variables Unicode, sont les suivants :
Langage de programmation | Type pour un seul caractère | Type pour tout texte |
---|---|---|
C | char[4] [0] ou wchar_t[2] [1] |
char[] ou wchar_t[] |
C++ | char[4] [0] ou wchar_t[2] [1] |
char[] ou wchar_t[] ou std::wstring |
Java | char[2] ou int [2] |
char[] ou String |
Bibliothèque ICU (pour C/C++ ou Java) | UChar |
UChar[] ou String , UnicodeString |
Javascript ou ECMAScript | char [3] |
string |
C# ou J# | char |
string |
Delphi | char[4] [0] ou widechar[2] |
string [0] ou widestring |
Python | unicode |
Notes :
- [0] En UTF-8
- [1] On notera toutefois que le type
wchar_t
du langage C ne permet pas toujours de coder tous les caractères Unicode, car la norme de ce langage ne prévoit pas de nombre minimum suffisante pour ce type standard. Cependant de nombreux compilateurs du langage définissentwchar_t
sur 32 bits (voire 64 bits sur les environnements manipulant les entiers standards sur 64 bits), ce qui suffit pour stocker n’importe quel point de code Unicode normalisé. Mais d’autres compilateurs représententwchar_t
sur 16 bits (notamment sous Windows en environnement 16 ou 32 bits), voire sur 8 bits seulement (notamment dans les environnements embarqués ne disposant pas d’un système d’exploitation d’usage général) carwchar_t
peut utiliser la même représentation que le typechar
qui compte un minimum de 8 bits. - [2] De manière similaire au C et au C++, le langage Java dispose de type unitaire permettant de coder 16 bits, mais ne permettant pas de coder un seul point de code d’une valeur quelconque (le type natif
char
est un entier positif sur 16 bits seulement). Pour manipuler les caractères normalisés hors du premier plan, il faut utiliser une paire de codets, chacun contenant une valeur égale aux deux codets définis par la forme UTF-16. Aussi les types d’objetsString
ouchar[2]
sont les plus appropriés pour représenter un caractère Unicode. Depuis Java 1.4.1, la bibliothèque standard fournit un support complet d’Unicode grâce au type natifint
(qui est un entier défini sur 32 bits) et aux méthodes statiques de la classe standardCharacter
(cependant un objet instancié de ce typeCharacter
ne permet pas, tout comme le type natifchar
, de stocker n’importe quel point de code). - [3] JavaScript comporte diverses implémentations non normalisées dont certaines plus anciennes ne supportent pas plus de 16 bits par caractère. Toutefois la norme ECMAScript de ce langage définit un type
char
sur 32 bits devant supporter tous les points de code des 17 plans normalisés. Ces deux langages ne supportent pas de typage explicite des variables, le type étant défini dynamiquement par les valeurs qu’on leur assigne (aussi, plusieurs représentations internes sont possibles, leurs différences étant normalement transparentes pour le programmeur).
Unicode souffre toutefois encore d’un faible support des expressions rationnelles par certains logiciels, même si des bibliothèques comme ICU et Java peuvent les supporter.
[modifier] Partitionnement
Le partitionnement à jour peut être trouvé sur le site officiel d’Unicode. Cependant, vu le rôle important d’Unicode, (ISO 10646) on décrira ici les principaux blocs de caractères. Les noms français sont les noms officiels de l’ISO/CEI 10646, la norme internationale bilingue qui reprend les mêmes caractères qu’Unicode. Ils sont aussi officiels que les noms anglais.
- L'ancienne norme Unicode 1.0 est obsolète et incompatible avec la norme ISO 10646 et la norme Unicode 1.1 et toutes ses versions ultérieures ; la principale incompatibilité est celle des blocs de caractères Hangul utilisés pour l’écriture de la langue coréenne qui ont changé de position et dont les anciens points de code ont depuis été assignés à d’autres blocs. La table ci-dessous est compatible avec ISO 10646 (toutes versions) et Unicode 1.1 (ou ultérieur).
Note : La casse des noms de bloc n’est pas normative. « Latin de base » est donc équivalent à « LATIN DE BASE ».
Points de code | Nom officiel du bloc | Commentaires | |
---|---|---|---|
Début | Fin | ||
0000 | FFFF | Plan multilingue de base (PMB) | |
0000 | 007F | Latin de base | voir norme ISO 646, code ASCII |
0080 | 009F | Non-utilisé | voir plage non-utilisé norme ISO 8859 et ISO 8859-1 |
00A0 | 00FF | Supplément Latin-1 | voir norme ISO 8859, code ISO 8859-1 |
0100 | 017F | Latin étendu A | |
0180 | 024F | Latin étendu B | |
0250 | 02AF | Alphabet phonétique international (API) | Alphabet phonétique international |
02B0 | 02FF | Lettres modificatives avec chasse | |
0300 | 036F | Diacritiques | voir Diacritique |
0370 | 03FF | Grec et copte | |
0400 | 04FF | Cyrillique | voir Alphabet cyrillique |
0500 | 052F | Supplément cyrillique | voir Alphabet cyrillique |
0530 | 058F | Arménien | voir langue Arménien |
0590 | 05FF | Hébreu | voir Alphabet hébreu |
0600 | 06FF | Arabe | voir alphabet arabe |
0700 | 074F | Syriaque | voir langue Syriaque |
0780 | 07BF | Thâna | |
0900 | 097F | Dévanâgarî | |
0980 | 09FF | Bengali | voir langue indienne Bengalî |
0A00 | 0A7F | Gourmoukhî | |
0A80 | 0AFF | Goudjerate | |
0B00 | 0B7F | Oriya | voir langue indienne Oriya |
0B80 | 0BFF | Tamoul | voir langue indienne Tamoul |
0C00 | 0C7F | Télougou | voir langue indienne Télougou |
0C80 | 0CFF | Kannara | voir langue indienne Kannara |
0D00 | 0D7F | Malayalam | voir langue indienne Malayalam |
0D80 | 0DFF | Singhalais | voir langue indo-européenne Cingalais |
0E00 | 0E7F | Thai | voir langue asiatique Thai |
0E80 | 0EFF | Lao | voir langue asiatique Lao |
0F00 | 0FFF | Tibétain | voir langue asiatique Tibétain |
1000 | 109F | Birman | voir langue asiatique Birman |
10A0 | 10FF | Géorgien | voir langue Géorgien |
1100 | 11FF | Jamos hangûl | |
1200 | 137F | Éthiopien | voir Alphabet éthiopien |
13A0 | 13FF | Chérokî | |
1400 | 167F | Syllabaires autochtones canadiens unifiés | |
1680 | 169F | Ogam | voir Écriture oghamique |
16A0 | 16FF | Runes | voir Alphabet runique |
1700 | 171F | Tagalog | ou tagal, voir langue Tagalog |
1720 | 173F | Hanounóo | |
1740 | 175F | Bouhide | |
1760 | 177F | Tagbanoua | |
1780 | 17FF | Khmer | voir langue Khmer |
1800 | 18AF | Mongol | voir langue mongol (Монгол хэл, mongγol kele) |
1900 | 194F | Limbou | |
1950 | 197F | Taï-le | |
19E0 | 19FF | Symboles khmers | voir langue Khmer |
1D00 | 1D7F | Supplément phonétique | |
1E00 | 1EFF | Latin étendu additionnel | |
1F00 | 1FFF | Grec étendu | |
2000 | 206F | Ponctuation générale | voir aussi ponctuation |
2070 | 209F | Exposants et indices | |
20A0 | 20CF | Symboles monétaires | |
20D0 | 20FF | Signes combinatoires pour symboles | |
2100 | 214F | Symboles de type lettre | |
2150 | 218F | Formes numérales | |
2190 | 21FF | Flèches | |
2200 | 22FF | Opérateurs mathématiques | voir Opérateurs mathématiques |
2300 | 23FF | Signes techniques divers | 2336 à 237A = symboles APL |
2400 | 243F | Pictogrammes de commande | |
2440 | 245F | Reconnaissance optique de caractères | voir Reconnaissance optique de caractères |
2460 | 24FF | Alphanumériques cerclés | |
2500 | 257F | Filets | |
2580 | 259F | Pavés | |
25A0 | 25FF | Formes géométriques | |
2600 | 26FF | Symboles divers | |
2700 | 27BF | Casseau | |
27C0 | 27EF | Divers symboles mathématiques - A | |
27F0 | 27FF | Supplément A de flèches | |
2800 | 28FF | Combinaisons Braille | voir Braille |
2900 | 297F | Supplément B de flèches | |
2980 | 29FF | Divers symboles mathématiques-B | |
2A00 | 2AFF | Opérateurs mathématiques supplémentaires | |
2B00 | 2BFF | Divers symboles et flèches | |
2D30 | 2D6F | Alphabet Tifinagh et néo-Tifinagh | voir Alphabet berbère et Tifinagh (langue berbère) |
2E80 | 2EFF | Formes supplémentaires des clés CJC | voir Chinois, japonais et coréen (CJC) |
2F00 | 2FDF | Clés chinoises (K'ang-hsi ou Kangxi) | voir Dictionnaire de caractères de Kangxi |
2FF0 | 2FFF | Description idéophonographique | |
3000 | 303F | Symboles et ponctuation CJC | voir ponctuation et Chinois, japonais et coréen (CJC) |
3040 | 309F | Hiragana | voir Hiragana (langue japonaise) |
30A0 | 30FF | Katakana | voir Katakana (langue japonaise) |
3100 | 312F | Bopomofo | voir Bopomofo (notation taïwanaise et chinoise) |
3130 | 318F | Jamos de compatibilité hangûls | |
3190 | 319F | Kanboun | |
31A0 | 31BF | Bopomofo étendu | voir Bopomofo (notation taïwanaise et chinoise) |
31F0 | 31FF | Extension phonétique katakana | voir Katakana (langue japonaise) |
3200 | 32FF | Lettres et mois CJC cerclés | voir Chinois, japonais et coréen (CJC) |
3300 | 33FF | Compatibilité CJC | voir Chinois, japonais et coréen (CJC) (unités de mesure) |
3400 | 4DB5 | Supplément A aux idéophonogrammes unifiés CJC | voir Chinois, japonais et coréen (CJC) |
4DC0 | 4DFF | Hexagrammes du Classique des mutations ou Yi-king | |
4E00 | 9FA5 | Idéophonogrammes unifiés CJC | voir Chinois, japonais et coréen (CJC) |
A000 | A48F | Syllabaire yi des Monts frais | |
A490 | A4CF | Clés yi | |
AC00 | D7A3 | Hangûl | |
D800 | DB7F | Demi-zone haute | points de code invalides isolément D800 à D83F : codets hauts utilisés en UTF-16 pour les points de code du plan multilingue complémentaire |
☒DB80 | DBFF | Partie à usage privé de la demi-zone haute | points de code invalides isolément DB80 à DBBF : codets hauts utilisés en UTF-16 pour les points de code de la zone supplémentaire A à usage privé |
DC00 | DFFF | Demi-zone basse | points de code invalides isolément
DC80 à DFFD : codets bas utilisés en UTF-16 pour des points de code assignés aux caractères valides ou réservés des plans complémentaires (assignés, réservés ou à usage privé) |
☒E000 | F8FF | Zone à usage privé | |
F900 | FAFF | Idéogrammes de compatibilité CJC | voir Chinois, japonais et coréen (CJC) |
FB00 | FB4F | Formes de présentation alphabétiques | |
FB50 | FDFF | Formes A de présentation arabes | voir alphabet arabe |
FDD0 | FDEF | non-caractères | |
FE00 | FE0F | Sélecteurs de variante | |
FE20 | FE2F | Demi-signes combinatoires | |
FE30 | FE4F | Formes de compatibilité CJC | voir Chinois, japonais et coréen (CJC) |
FE50 | FE6F | Petites variantes de forme | |
FE70 | FEFF | Formes B de présentation arabes | |
FF00 | FFEF | Formes de demi et pleine chasse | |
FFF0 | FFFD | Caractères spéciaux | |
FFFE | FFFF | non-caractères | |
10000 | 1FFFF | Plan multilingue complémentaire (PMC) | |
10000 | 1007F | Syllabaire linéaire B ou syllabaire mycénien | |
10080 | 100FF | Idéogrammes du linéaire B | |
10100 | 1013F | Nombres égéens | |
10300 | 1032F | Alphabet italique | |
10330 | 1034F | Gotique | voir langue Gotique |
10380 | 1039F | Ougaritique | voir langue Ougaritique |
10400 | 1044F | Déséret | |
10450 | 1047F | Shavien | |
10480 | 104AF | Osmanya | |
10800 | 1083F | Syllabaire chypriote | |
1D000 | 1D0FF | Symboles musicaux byzantins | |
1D100 | 1D1FF | Symboles musicaux occidentaux | |
1D300 | 1D35F | Symboles du Classique du mystère suprême | |
1D400 | 1D7FF | Symboles mathématiques alphanumériques | |
1FFFE | 1FFFF | non-caractères | |
20000 | 2FFFF | Plan idéographique complémentaire (PIC) | |
20000 | 2A6D6 | Supplément B aux idéogrammes unifiés CJC | |
2F800 | 2FA1F | Supplément aux idéogrammes de compatibilité CJC | |
2FFFE | 2FFFF | non-caractères | |
30000 | DFFFF | Plans complémentaires réservés | |
3FFFE | 3FFFF | non-caractères | |
4FFFE | 4FFFF | non-caractères | |
5FFFE | 5FFFF | non-caractères | |
6FFFE | 6FFFF | non-caractères | |
7FFFE | 7FFFF | non-caractères | |
8FFFE | 8FFFF | non-caractères | |
9FFFE | 9FFFF | non-caractères | |
AFFFE | AFFFF | non-caractères | |
BFFFE | BFFFF | non-caractères | |
CFFFE | CFFFF | non-caractères | |
DFFFE | DFFFF | non-caractères | |
E0000 | EFFFF | Plan complémentaire spécialisé (PCS) | |
E0000 | E007F | Étiquettes | |
E0100 | E01EF | Supplément de sélecteurs de variante | |
EFFFE | EFFFF | non-caractères | |
F0000 | 10FFFF | Plans complémentaires à usage privé | |
☒F0000 | FFFFD | Zone supplémentaire A à usage privé | |
FFFFE | FFFFF | non-caractères | |
☒100000 | 10FFFD | Zone supplémentaire B à usage privé | |
10FFFE | 10FFFF | non-caractères |
Les zones à usage privé indiquées par le symbole ☒ ne contiennent pas les mêmes œils d’une police à l’autre et doivent donc être évités pour le codage de textes destinés aux échanges entre systèmes hétérogènes. Toutefois ces points de codes à usage privé sont valides et peuvent être utilisés dans tout traitement automatisé conforme aux normes Unicode et ISO 10646, y compris entre systèmes différents s’il existe un accord mutuel privé concernant leur usage.
En l’absence d’accord entre les deux parties, des systèmes utilisant ces caractères peuvent rejeter les textes les contenant, car les traitements qu’ils leur font subir pourraient ne pas fonctionner correctement ou causer des problèmes de sécurité; les autres systèmes qui n’attribuent aucune fonction spéciale à ces caractères doivent en revanche les accepter comme valides et les conserver comme partie intégrante des textes, comme s’il s’agissait de symboles graphiques, même s’ils ne savent pas les afficher correctement.
Les non-caractères listés sont des points de code valides, mais ils ne sont pas (et ne seront jamais) assignés à des caractères normalisés. Leur usage dans le codage de textes transmis entre systèmes (même si identiques) est interdit, car il est impossible de les rendre compatibles avec les formes de transformation universelles normalisées (dont UTF-8, UTF-16, UTF-32) les schémas de codage correspondants, et les autres codages normalisés compatibles avec Unicode et ISO 10646 (BOCU-1, SCSU, différentes versions de la norme chinoise GB18030, etc.). Toutefois certains systèmes les génèrent et les utilisent localement, mais pour un traitement strictement interne destiné à faciliter l’implémentation des algorithmes de traitement de textes utilisant les autres caractères normalisés.
Parmi ces derniers non-caractères figurent les points de code valides mais réservés aux demi-zones (privées ou non). Ces points de code ne peuvent pas être utilisés individuellement pour coder un caractère. Ils servent uniquement pour la forme de transformation universelle UTF-16 (et les schémas de codage correspondants) pour représenter sur deux codets (à 16 bits chacun) des points de code valides dans un des 16 plans complémentaires (certaines combinaisons de codets correspondent à des caractères valides de ces plans, standards ou privés, d’autres combinaisons peuvent ne représenter aucun caractère valide car elles correspondraient à des non-caractères de ces plans complémentaires, et sont donc interdites dans les textes conformes à la norme).
Les autres zones libres (non assignées à un bloc nommé normalisé, ou les points de code laissés libres et réservés dans les blocs nommés existants) sont réservés pour un usage ultérieur dans des versions futures d’Unicode et ISO 10646, mais sont valides. Tout système traitant des textes contenant ces points de code réservés doivent les accepter sans les filtrer. Unicode définit des propriétés par défaut pour les hypothétiques caractères correspondants, afin de préserver la compatibilité des systèmes (conformes à la norme Unicode) avec les futurs textes conformes qui les contiendraient. Aucune application conforme ne doit leur assigner un caractère ou une sémantique spéciale (les zones privées sont destinées à cet usage).
[modifier] Voir aussi
[modifier] Liens internes
- Caractères APL/APL2 en Unicode
- Caractères asiatiques
- DejaVu
- Duplication de caractères unicode
- EBCDIC
- ISO 646, ASCII
- ISO/CEI 10646
- Stringprep
- Table des caractères Unicode
- Liste de caractères Unicode latins précomposés
[modifier] Liens externes
[modifier] Références normatives
- (en) Page d’accueil du consortium Unicode.
- (fr) Traduction française officielle de l’ISO/CEI 10646 et Unicode.
- (fr) Tables de caractères Unicode annotées avec les équivalences.
- (en) Ordonnancement Unicode normalisé (pour le classement ou le tri).
- (en) RFC 3718, RFC 3629, RFC 3492, RFC 2482, RFC 1642, RFC 1641.
[modifier] Références non officielles
- (fr) Unicode 5.0 en pratique paru chez Dunod en avril 2008.
- (en) (de) decodeunicode, Unicode-Wiki, tous les 98 884 caractères d’Unicode en images.
- (en) Site recensant les différents blocs d’Unicode avec pages de tests, conseils et liens vers les polices permettant d’afficher les blocs en question.
- (fr) Table des caractères Unicode de 1 à 65 535.
- (fr) Chapitres 2, 3, et 4 du livre Fontes et codages.
- (fr) Présentation du codage de caractères phonétiques à l’aide d’Unicode, à l’usage des novices.
- (fr) Unicode, écriture du monde ? (vol.6 (2003) de la revue Document numérique, 364 pages). Intérêt : points de vue critiques (typographes, informaticiens, égyptologues, etc.) et entretien avec Ken Whistler, directeur technique du Consortium Unicode.
- (en) The Gallery of Unicode Fonts : inventaire de 1 239 fontes (août 2007) et des caractères qu’elles comprennent.
[modifier] Utilisation d’Unicode
- (fr) Exemple d’utilisation d’Unicode et tests.
- (en) Comment utiliser Unicode sur les systèmes libres GNU/Linux ou compatibles.
[modifier] Utilitaires pour l’exploitation d’Unicode
- (fr) Graticiel BabelMap, visualisation et recherche des caractères des polices Unicodes, de leurs propriétés et de leurs codages UTF-8, UTF-16, UTF-32.
- (fr) The Unicode Sliderule, outil Internet de saisie de caractères Unicode.
- un clavier pour taper tous les caractères unicode dans firefox
[modifier] Articles et discussions
- (en) Markus Kuhn, UTF-8 and Unicode FAQ
- (en) Otfried Cheong, UniHan (article sur les problèmes d’unification des sinogrammes avec UniHan dans Unicode)
- (fr) Vos applications Web en Unicode, (article et tutoriel sur la mise en pratique d'Unicode avec PHP et MySQL ainsi que l’implémentation côté client dans les documents XML, HTML et CSS)
[modifier] Références
- ↑ (en)The Unicode Standard, Version 5.0, Chapter 16 : Special Areas and Format Characters, p354
- ↑ Les séquences UTF-8 doivent être les plus courtes possibles. Cette restriction doit être vérifiée pour éviter certaines failles de sécurité, du type "/../" – se reporter aux détails dans la section « Inconvénients » de l'article UTF-8.