Pourquoi avons-nous besoin d'Unicode?
Au début (pas trop), tout ce qui existait était ASCII. Ce n'était pas grave, car il suffirait de quelques caractères de contrôle, de ponctuation, de chiffres et de lettres comme ceux de cette phrase. Malheureusement, le monde étrange actuel des intercommunications mondiales et des médias sociaux n'était pas prévu, et il n'est pas trop inhabituel de voir l'anglais, le العربية, le עִבְ, le עִבְרִית, le ελληνικά et le ភាសាខ្មែរ dans le même document (j'espère que je n'ai pas cassé de vieux navigateurs).
Mais pour l'argument, disons que Joe Average est un développeur de logiciels. Il insiste sur le fait qu'il n'aura besoin que de l'anglais et, en tant que tel, ne souhaite utiliser que l'ASCII. Cela peut convenir à Joe, l' utilisateur , mais ce ne l'est pas à Joe , développeur de logiciels . Environ la moitié du monde utilise des caractères non latins et l'utilisation de l'ASCII est sans doute inconsidérée pour ces personnes, et en plus de cela, il ferme son logiciel à une économie grande et en croissance.
Par conséquent, un jeu de caractères englobant comprenant toutes les langues est nécessaire. C'est ainsi qu'est venu Unicode. Il attribue à chaque caractère un numéro unique appelé point de code . Un avantage d'Unicode par rapport aux autres ensembles possibles est que les 256 premiers points de code sont identiques à ISO-8859-1 , et donc également ASCII. De plus, la grande majorité des caractères couramment utilisés ne sont représentables que sur deux octets, dans une région appelée le plan multilingue de base (BMP) . Maintenant, un encodage de caractères est nécessaire pour accéder à ce jeu de caractères, et comme la question le demande, je vais me concentrer sur UTF-8 et UTF-16.
Considérations sur la mémoire
Alors, combien d'octets donnent accès à quels caractères dans ces encodages?
- UTF-8:
- 1 octet: ASCII standard
- 2 octets: arabe, hébreu, la plupart des scripts européens (notamment géorgien )
- 3 octets: BMP
- 4 octets: tous les caractères Unicode
- UTF-16:
- 2 octets: BMP
- 4 octets: tous les caractères Unicode
Il convient de mentionner maintenant que les caractères ne figurant pas dans le BMP comprennent des scripts anciens, des symboles mathématiques, des symboles musicaux et des caractères chinois / japonais / coréens (CJK) plus rares .
Si vous travaillez principalement avec des caractères ASCII, alors UTF-8 est certainement plus efficace en mémoire. Cependant, si vous travaillez principalement avec des scripts non européens, l'utilisation de l'UTF-8 pourrait être jusqu'à 1,5 fois moins efficace en mémoire que l'UTF-16. Lorsque vous traitez de grandes quantités de texte, telles que de grandes pages Web ou de longs documents Word, cela peut affecter les performances.
Bases de l'encodage
Remarque: Si vous savez comment UTF-8 et UTF-16 sont codés, passez à la section suivante pour les applications pratiques.
- UTF-8: Pour les caractères ASCII standard (0-127), les codes UTF-8 sont identiques. Cela rend l'UTF-8 idéal si une compatibilité descendante est requise avec le texte ASCII existant. Les autres caractères nécessitent entre 2 et 4 octets. Cela se fait en réservant quelques bits dans chacun de ces octets pour indiquer qu'il fait partie d'un caractère multi-octets. En particulier, le premier bit de chaque octet est
1
destiné à éviter les conflits avec les caractères ASCII.
- UTF-16: pour les caractères BMP valides, la représentation UTF-16 est simplement son point de code. Cependant, pour les caractères non BMP, UTF-16 introduit des paires de substitution . Dans ce cas, une combinaison de deux parties de deux octets correspond à un caractère non BMP. Ces portions de deux octets proviennent de la plage numérique BMP, mais sont garanties par la norme Unicode comme non valides en tant que caractères BMP. De plus, comme UTF-16 a deux octets comme unité de base, il est affecté par l' endianité . Pour compenser, une marque d'ordre d'octets réservés peut être placée au début d'un flux de données qui indique l'endianité. Ainsi, si vous lisez l'entrée UTF-16 et qu'aucune endianité n'est spécifiée, vous devez vérifier cela.
Comme on peut le voir, UTF-8 et UTF-16 sont loin d'être compatibles entre eux. Donc, si vous faites des E / S, assurez-vous de savoir quel encodage vous utilisez! Pour plus de détails sur ces encodages, veuillez consulter la FAQ UTF .
Considérations pratiques de programmation
Types de données de caractères et de chaînes: comment sont-ils codés dans le langage de programmation? S'ils sont des octets bruts, la minute où vous essayez de sortir des caractères non ASCII, vous pouvez rencontrer quelques problèmes. De plus, même si le type de caractère est basé sur un UTF, cela ne signifie pas que les chaînes sont du bon UTF. Ils peuvent autoriser des séquences d'octets illégales. En règle générale, vous devrez utiliser une bibliothèque qui prend en charge UTF, comme ICU pour C, C ++ et Java. Dans tous les cas, si vous souhaitez entrer / sortir autre chose que l'encodage par défaut, vous devrez d'abord le convertir.
Encodages recommandés / par défaut / dominants: lorsque vous avez le choix de l'UTF à utiliser, il est généralement préférable de suivre les normes recommandées pour l'environnement dans lequel vous travaillez. Par exemple, l'UTF-8 est dominant sur le Web, et depuis HTML5, il a été l' encodage recommandé . Inversement, les environnements .NET et Java sont basés sur un type de caractère UTF-16. De manière confuse (et incorrecte), des références sont souvent faites au "codage Unicode", qui fait généralement référence au codage UTF dominant dans un environnement donné.
Prise en charge des bibliothèques: les bibliothèques que vous utilisez prennent en charge une sorte d'encodage. Laquelle? Soutiennent-ils les cas d'angle? Étant donné que la nécessité est la mère de l'invention, les bibliothèques UTF-8 prennent généralement en charge correctement les caractères à 4 octets, car des caractères à 1, 2 et même 3 octets peuvent apparaître fréquemment. Cependant, toutes les bibliothèques UTF-16 prétendues ne prennent pas correctement en charge les paires de substitution, car elles se produisent très rarement.
Compter les caractères: Il existe des combinaisons de caractères en Unicode. Par exemple, le point de code U + 006E (n) et U + 0303 (un tilde combinant) forment ñ, mais le point de code U + 00F1 forme ñ. Ils devraient être identiques, mais un simple algorithme de comptage renverra 2 pour le premier exemple, 1 pour le second. Ce n'est pas nécessairement faux, mais ce n'est peut-être pas le résultat souhaité non plus.
Comparaison pour l'égalité: A, А et Α se ressemblent, mais ils sont respectivement latin, cyrillique et grec. Vous avez également des cas comme C et Ⅽ, l'un est une lettre, l'autre un chiffre romain. De plus, nous avons également à considérer les caractères de combinaison. Pour plus d'informations, voir Dupliquer les caractères dans Unicode .
Paires de substitution: elles apparaissent assez souvent sur SO, je vais donc fournir quelques exemples de liens:
Autres?: