487 votes

Qu'est-ce que Unicode, UTF-8 et UTF-16?

Quelle est la base de Unicode et pourquoi le besoin d'UTF-8 ou UTF-16? J'ai fait des recherches sur Google et également recherché ici, mais ce n'est pas clair pour moi.

Dans VSS, lorsqu'on effectue une comparaison de fichiers, il arrive parfois qu'un message indique que les deux fichiers ont des UTF différents. Pourquoi serait-ce le cas?

Veuillez expliquer en termes simples.

153 votes

Il semble que vous avez besoin de lire Le strict minimum que tout développeur de logiciel doit absolument savoir sur Unicode et les jeux de caractères! C'est une très bonne explication de ce qui se passe.

0 votes

Introduction plus courte de mon blog. Elle a été obtenue à partir de l'article de Joel, mais appliquée à un problème spécifique.

5 votes

Cette FAQ du site web officiel d'Unicode a quelques réponses pour vous.

679voto

DPenner Points 2052

Pourquoi avons-nous besoin d'Unicode ?

À l'époque (pas si lointaine), tout ce qui existait était ASCII. Ce n'était pas grave, car tout ce dont on avait besoin, c'était de quelques caractères de contrôle, de la ponctuation, des chiffres et des lettres comme celles de cette phrase. Malheureusement, le monde étrange de l'intercommunication mondiale et des médias sociaux d'aujourd'hui n'était pas prévu, et il n'est pas inhabituel de voir l'anglais, , , , , et dans le même document (j'espère que je n'ai pas cassé de vieux navigateurs).

Mais, à titre d'exemple, disons que Joe Average est un développeur de logiciels. Il insiste sur le fait qu'il n'aura jamais besoin que de l'anglais, et ne veut donc utiliser que l'ASCII. Cela peut convenir à Joe moyen utilisateur mais cela ne convient pas à Joe, le développeur de logiciels . Environ la moitié du monde utilise des caractères non latins et l'utilisation de l'ASCII est sans doute un manque de considération pour ces personnes. De plus, il ferme son logiciel à une économie importante et en pleine croissance.

Par conséquent, un jeu de caractères englobant comprenant todo des langues est nécessaire. C'est ainsi qu'est né Unicode. Il attribue à chaque caractère un numéro unique appelé un point de code . L'un des avantages d'Unicode par rapport à d'autres ensembles possibles est que les 256 premiers points de code sont identiques aux points de code de l'Union européenne. ISO-8859-1 et donc aussi ASCII. En outre, la grande majorité des caractères couramment utilisés ne sont représentables que par deux octets, dans une région appelée le Plan de base multilingue (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 relatives à la mémoire

Ainsi, combien d'octets donnent accès à quels caractères dans ces codages ?

  • UTF-8 :
    • 1 octet : ASCII standard
    • 2 octets : L'arabe, l'hébreu, la plupart des écritures européennes (à l'exception notamment de l'anglais). 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 qui ne figurent pas dans le BMP comprennent des écritures anciennes, des symboles mathématiques, des symboles musicaux et des caractères plus rares. Chinois/Japonais/Coréen (CJK) des personnages.

Si vous travaillez principalement avec des caractères ASCII, UTF-8 est certainement plus efficace en termes de mémoire. Toutefois, si vous travaillez principalement avec des scripts non européens, l'utilisation d'UTF-8 peut être jusqu'à 1,5 fois moins efficace en termes de mémoire qu'UTF-16. Lorsque vous traitez de grandes quantités de texte, comme des pages Web volumineuses ou de longs documents Word, cela peut avoir un impact sur les performances.

Les bases du codage

Remarque : si vous savez comment sont codés les UTF-8 et UTF-16, 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 rétrocompatibilité est requise avec le texte ASCII existant. D'autres caractères nécessitent entre 2 et 4 octets. Pour ce faire, certains bits sont réservés dans chacun de ces octets pour indiquer qu'ils font partie d'un caractère à plusieurs octets. En particulier, le premier bit de chaque octet est 1 pour ne pas entrer en conflit 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, l'UTF-16 introduit paires de substituts . Dans ce cas, une combinaison de deux portions de deux octets correspond à un caractère non BMP. Ces portions de deux octets proviennent de la gamme numérique BMP, mais sont garanties par la norme Unicode comme étant invalides en tant que caractères BMP. De plus, comme l'UTF-16 a deux octets comme unité de base, il est affecté par les éléments suivants endiveté . Pour compenser, une réserve marque de l'ordre des octets peut être placé au début d'un flux de données qui indique l'endianness. Ainsi, si vous lisez une entrée UTF-16, et qu'aucun endianness n'est spécifié, vous devez le vérifier.

Comme on peut le constater, UTF-8 et UTF-16 sont loin d'être compatibles l'un avec l'autre. Donc, si vous effectuez des E/S, assurez-vous de savoir quel encodage vous utilisez ! Pour plus de détails sur ces encodages, veuillez consulter la page FAQ UTF .

Considérations pratiques sur la programmation

Types de données Character et String : Comment sont-ils codés dans le langage de programmation ? S'il s'agit d'octets bruts, dès que vous essayez de sortir des caractères non ASCII, vous risquez de rencontrer quelques problèmes. En outre, même si le type de caractère est basé sur un UTF, cela ne signifie pas que les chaînes de caractères sont des UTF corrects. Elles peuvent autoriser des séquences d'octets qui sont illégales. En général, vous devrez utiliser une bibliothèque qui prend en charge UTF, telle que UNITÉ DE SOINS INTENSIFS pour C, C++ et Java. Dans tous les cas, si vous voulez entrer/sortir quelque chose d'autre que l'encodage par défaut, vous devrez d'abord le convertir.

Encodements 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 est l'UTF le plus utilisé. codage recommandé . À l'inverse, les environnements .NET et Java reposent tous deux sur un type de caractère UTF-16. De manière confuse (et incorrecte), il est souvent fait référence à l'"encodage Unicode", qui fait généralement référence à l'encodage UTF dominant dans un environnement donné.

Soutien aux bibliothèques : Les bibliothèques que vous utilisez supportent un certain type d'encodage. Lequel ? Prennent-elles en charge les cas particuliers ? La nécessité étant la mère de l'invention, les bibliothèques UTF-8 prennent généralement en charge correctement les caractères de 4 octets, puisque les caractères de 1, 2 et même 3 octets sont fréquents. Cependant, toutes les bibliothèques UTF-16 ne supportent pas correctement les paires de substituts car elles sont très rares.

Compter les caractères : Il existe en combinant caractères dans Unicode. Par exemple, le point de code U+006E (n), et U+0303 (un tilde de combinaison) forme ñ, mais le point de code U+00F1 forme ñ. Ils devraient sembler identiques, mais un simple algorithme de comptage retournera 2 pour le premier exemple, 1 pour le second. Ce n'est pas nécessairement faux, mais ce n'est peut-être pas non plus le résultat souhaité.

Comparaison pour l'égalité : A, А et Α se ressemblent, mais ils sont respectivement en latin, en cyrillique et en grec. Vous avez aussi des cas comme C et Ⅽ, l'un est une lettre, l'autre un chiffre romain. En outre, nous devons également tenir compte des caractères de combinaison. Pour plus d'informations, voir Caractères dupliqués dans Unicode .

Paires de substituts : Ces questions reviennent assez souvent sur l'OS, je me contenterai donc de fournir quelques exemples de liens :

D'autres ?

11 votes

Excellente réponse, de grandes chances pour la prime ;-) Personnellement, je rajouterais que certains plaident en faveur de l'UTF-8 comme codage universel des caractères, mais je sais que ce n'est pas une opinion partagée par tout le monde.

0 votes

Merci! Personnellement, je suis indécis dans tout ce débat sur UTF-8 / UTF-16 (et UTF-32), mais avec ce post, j'espérais clarifier l'état actuel pratique des choses. Cependant, je pense que le débat sur l'encodage est beaucoup moins important que de savoir comment gérer correctement les encodages que vous utilisez.

3 votes

Encore trop technique pour moi à ce stade. Comment est stocké le mot bonjour dans un ordinateur en UTF-8 et UTF-16 ?

95voto

wengeezhang Points 1
  • Unicode
    • est un ensemble de caractères utilisé dans le monde entier
  • UTF-8
    • un encodage de caractères capable d'encoder tous les caractères possibles (appelés points de code) dans Unicode.
    • l'unité de code est de 8 bits
    • utilisez une à quatre unités de code pour encoder Unicode
    • 00100100 pour "$" (un octet de 8 bits); 11000010 10100010 pour "¢" (deux octets de 8 bits); 11100010 10000010 10101100 pour "" (trois octets de 8 bits)
  • UTF-16
    • un autre encodage de caractères
    • l'unité de code est de 16 bits
    • utilisez une à deux unités de code pour encoder Unicode
    • 00000000 00100100 pour "$" (un octet de 16 bits); 11011000 01010010 11011111 01100010 pour "

0 votes

Le caractère avant "two 16-bits" ne s'affiche pas (version Firefox 97.0 sur Ubuntu MATE 20.04 (Focal Fossa)).

35voto

Neuron Points 385

Unicode est une norme assez complexe. Ne soyez pas trop effrayé, mais soyez prêt à travailler un peu! [2]

Parce qu'une ressource crédible est toujours nécessaire, mais le rapport officiel est énorme, je suggère de lire ce qui suit:

  1. Le minimum absolu que tout développeur de logiciels doit absolument connaître sur Unicode et les jeux de caractères (Pas d'excuses!) Une introduction de Joel Spolsky, PDG de Stack Exchange.
  2. Vers le BMP et au-delà! Un tutoriel d'Eric Muller, directeur technique à l'époque, puis vice-président plus tard, au Consortium Unicode (les 20 premières diapositives et c'est bon)

Une brève explication:

Les ordinateurs lisent des octets et les humains lisent des caractères, nous utilisons donc des normes d'encodage pour mapper les caractères aux octets. L'ASCII était la première norme largement utilisée, mais ne couvre que le latin (sept bits par caractère peuvent représenter 128 caractères différents). Unicode est une norme ayant pour objectif de couvrir tous les caractères possibles dans le monde (peut contenir jusqu'à 1 114 112 caractères, soit un maximum de 21 bits par caractère. Unicode 8.0 actuel spécifie au total 120 737 caractères, et c'est tout).

La principale différence est qu'un caractère ASCII peut tenir dans un octet (huit bits), mais la plupart des caractères Unicode ne le peuvent pas. Ainsi, des formes/schémas d'encodage (comme UTF-8 et UTF-16) sont utilisés, et le modèle de caractère se présente comme suit:

Chaque caractère détient une position énumérée de 0 à 1 114 111 (hex: 0-10FFFF) appelée un _point de code_.
Une forme d'encodage mappe un point de code à une séquence d'unités de code. Une unité de code est la manière dont vous voulez organiser les caractères en mémoire, des unités de 8 bits, des unités de 16 bits, etc. UTF-8 utilise une à quatre unités de huit bits, et UTF-16 utilise une ou deux unités de 16 bits, pour couvrir l'ensemble du Unicode avec un maximum de 21 bits. Les unités utilisent des préfixes afin que les limites des caractères puissent être repérées, et plus d'unités signifient plus de préfixes qui occupent des bits. Ainsi, bien que UTF-8 utilise un octet pour l'écriture latine, il lui faut trois octets pour les scripts ultérieurs à l'intérieur d'un plan multilingue de base, tandis que UTF-16 utilise deux octets pour tous ceux-ci. Et c'est leur principale différence.
Enfin, un schéma d'encodage (comme UTF-16BE ou UTF-16LE) mappe (sérialise) une séquence d'unités de code en une séquence d'octets.

caractère: π
point de code: U+03C0
formes d'encodage (unités de code):
      UTF-8: CF 80
      UTF-16: 03C0
schémas d'encodage (octets):
      UTF-8: CF 80
      UTF-16BE: 03 C0
      UTF-16LE: C0 03

Conseil: un chiffre hexadécimal représente quatre bits, donc un nombre hexadécimal à deux chiffres représente un octet.
Jetez également un œil aux cartes des plans sur Wikipedia pour avoir une idée de la disposition de l'ensemble de caractères.

0 votes

Joel Spolsky n'est plus le PDG.

33voto

InGeek Points 1932

L'article Ce que tout programmeur doit absolument savoir sur les encodages et les jeux de caractères pour travailler avec du texte explique tous les détails.

Écriture dans le tampon

Si vous écrivez dans un tampon de 4 octets, le symbole avec l'encodage UTF8, votre contenu binaire ressemblera à ceci :

00000000 11100011 10000001 10000010

Si vous écrivez dans un tampon de 4 octets, le symbole avec l'encodage UTF16, votre contenu binaire ressemblera à ceci :

00000000 00000000 00110000 01000010

Comme vous pouvez le voir, selon la langue que vous utilisez dans votre contenu, cela affectera votre mémoire en conséquence.

Exemple : Pour ce symbole particulier : l'encodage UTF16 est plus efficace car nous avons 2 octets supplémentaires à utiliser pour le symbole suivant. Mais cela ne signifie pas que vous devez utiliser UTF16 pour l'alphabet japonais.

Lecture depuis le tampon

Maintenant, si vous voulez lire les octets ci-dessus, vous devez savoir dans quel encodage ils ont été écrits et les décoder correctement.

Par exemple, si vous décodez ceci : 00000000 11100011 10000001 10000010 en encodage UTF16, vous obtiendrez et non

Remarque : L'encodage et l'Unicode sont deux choses différentes. L'Unicode est la grande (table) avec chaque symbole correspondant à un point de code unique. Par exemple, le symbole (lettre) a un (point de code) : 30 42 (hexadécimal). L'encodage, en revanche, est un algorithme qui convertit les symboles de manière plus appropriée lors de leur stockage sur le matériel.

30 42 (hex) - > encodage UTF8 - > E3 81 82 (hex), qui donne le résultat ci-dessus en binaire.

30 42 (hex) - > encodage UTF16 - > 30 42 (hex), qui donne le résultat ci-dessus en binaire.

Entrez une description de l'image ici

0 votes

Une excellente réponse, que j'ai votée. Seriez-vous assez aimable pour vérifier si cette partie de votre réponse est telle que vous l'aviez prévue (car cela n'a pas de sens): "converts symbols to more appropriate way".

1 votes

Le titre de la référence, "Ce que tout programmeur doit absolument et positivement savoir sur les codages et les jeux de caractères pour travailler avec du texte", est proche du plagiat du "Le strict minimum que tout développeur de logiciels doit absolument et positivement connaître sur Unicode et les jeux de caractères (Pas d'excuses !)" de Joel Spolsky.

22voto

dan04 Points 33306

À l'origine, Unicode était destiné à avoir un encoding fixe sur 16 bits (UCS-2). Les premiers utilisateurs d'Unicode, comme Java et Windows NT, ont construit leurs bibliothèques autour de chaînes sur 16 bits.

Plus tard, la portée d'Unicode a été étendue pour inclure des caractères historiques, ce qui nécessiterait plus que les 65 536 points de code qu'un encodage sur 16 bits pourrait supporter. Pour permettre la représentation des caractères supplémentaires sur des plates-formes qui utilisaient UCS-2, l'encodage UTF-16 a été introduit. Il utilise des "paires de substitution" pour représenter les caractères dans les plans supplémentaires.

Pendant ce temps, beaucoup de logiciels anciens et de protocoles de réseau utilisaient des chaînes sur 8 bits. UTF-8 a été créé pour que ces systèmes puissent prendre en charge Unicode sans avoir à utiliser de larges caractères. Il est rétrocompatible avec l'ASCII sur 7 bits.

4 votes

Il convient de noter que Microsoft continue de se référer à l'UTF-16 comme Unicode, ce qui ajoute à la confusion. Les deux ne sont pas pareils.

0 votes

Pas rare que Microsoft "ajoute à la confusion".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X