web-dev-qa-db-fra.com

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

Quelle est la base de l'Unicode et pourquoi la nécessité de UTF-8 ou UTF-16??. J'ai effectué des recherches à ce sujet sur Google et j'ai effectué une recherche ici également, mais ce n'est pas clair pour moi. 

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

S'il vous plaît expliquer en termes simples.

318
SoftwareGeek

Pourquoi avons-nous besoin de l'Unicode?

Au début (pas trop), tout ce qui existait était ASCII. C’était acceptable, car il ne faudrait plus que quelques caractères de contrôle, de la ponctuation, des chiffres et des lettres comme ceux de cette phrase. Malheureusement, le monde étrange d'aujourd'hui, caractérisé par une intercommunication globale et les médias sociaux, n'était pas prévu et il n'est pas inhabituel de voir l'anglais, le العربية, le, le רִית, le ελληνικά et le dans le même document (j'espère n'avoir brisé aucun navigateurs).

Mais pour les besoins de l’argument, 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, à ce titre, ne souhaite utiliser que l'ASCII. Cela pourrait convenir à Joe l'utilisateur , mais cela ne convient pas à Joe le développeur de logiciels . Environ la moitié du monde utilise des caractères non latins. L'utilisation de ASCII est sans aucun doute une indifférence pour ces personnes. De plus, il ferme son logiciel à une économie de grande taille et en pleine croissance.

Par conséquent, un jeu de caractères englobant comprenant toutes les langues est nécessaire. Ainsi vint Unicode. Il attribue à chaque caractère un numéro unique appelé point de code. L'un des avantages 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. En outre, la grande majorité des caractères couramment utilisés ne peuvent être représentés que par deux octets, dans une région appelée Plan multilingue de base (BMP) . Maintenant, un codage de caractères est nécessaire pour accéder à ce jeu de caractères et, comme le demande la question, je me concentrerai 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?

  • TF-8:
    • 1 octet: ASCII standard
    • 2 octets: arabe, hébreu, la plupart des écritures européennes (notamment géorgien )
    • 3 octets: BMP
    • 4 octets: tous les caractères Unicode
  • TF-16:
    • 2 octets: BMP
    • 4 octets: tous les caractères Unicode

Il est à noter que les caractères qui ne figurent pas dans BMP incluent des scripts anciens, des symboles mathématiques, des symboles musicaux et des caractères plus rares Chinois/Japonais/Coréen (CJK) .

Si vous travaillez principalement avec les 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 de UTF-8 peut nécessiter jusqu’à 1,5 fois moins d’efficacité de la mémoire que celle d’UTF-16. Lorsque vous traitez de grandes quantités de texte, telles que des pages Web volumineuses ou des documents Word volumineux, cela peut avoir un impact sur les performances.

Les 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.

  • TF-8: Pour les caractères standard ASCII (0-127), les codes UTF-8 sont identiques. Cela rend UTF-8 idéal si une compatibilité ascendante est requise avec le texte ASCII existant. D'autres caractères nécessitent entre 2 et 4 octets. Ceci est 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 afin d'éviter toute collision avec les caractères ASCII.
  • TF-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 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 BMP caractères. De plus, comme UTF-16 a deux octets comme unité de base, il est affecté par endianness . Pour compenser, une marque réservée byte order mark peut être placée au début d'un flux de données, ce qui indique une finalité. Ainsi, si vous lisez l'entrée UTF-16 et qu'aucune finalité n'est spécifiée, vous devez vérifier cela.

Comme on peut le constater, les formats UTF-8 et UTF-16 sont loin d’être compatibles entre eux. Donc, si vous faites des E/S, assurez-vous de connaître le codage que vous utilisez! Pour plus de détails sur ces encodages, veuillez vous référer à TF FAQ .

Considérations pratiques de programmation

Types de données Caractère et Chaîne: Comment sont-ils codés dans le langage de programmation? S'il s'agit d'octets bruts, à la minute où vous essayez de générer des caractères non-ASCII, vous pouvez rencontrer quelques problèmes. De même, même si le type de caractère est basé sur un fichier UTF, cela ne signifie pas que les chaînes sont au format UTF. Ils peuvent autoriser des séquences d'octets illégales. En règle générale, vous devez utiliser une bibliothèque prenant en charge UTF, telle que ICU pour C, C++ et Java. Dans tous les cas, si vous voulez entrer/sortir autre chose que le codage par défaut, vous devrez d'abord le convertir.

Codages recommandés/par défaut/dominants: Lorsque vous devez choisir le format UTF à utiliser, il est généralement préférable de respecter les normes recommandées pour l'environnement dans lequel vous travaillez. Par exemple, UTF-8 est dominant sur le marché. Web, et depuis HTML5, il s’agit du codage recommandé . Inversement, les environnements .NET et Java reposent sur un type de caractère UTF-16. De façon confuse (et incorrecte), il est souvent fait référence au "codage Unicode", qui fait généralement référence au codage UTF dominant dans un environnement donné.

Support de bibliothèque: Les bibliothèques que vous utilisez supportent un certain type de codage. Laquelle? Soutiennent-ils les cas d'angle? Puisque la nécessité est la mère de l'invention, les bibliothèques UTF-8 supporteront généralement correctement les caractères de 4 octets, car des caractères de 1, 2 et même de 3 octets peuvent apparaître fréquemment. Cependant, toutes les bibliothèques UTF-16 supposées ne prennent pas correctement en charge les paires de substitution car elles sont très rares.

Nombre de caractères: Il existe des caractères combinant 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 sembler identiques, mais un algorithme de comptage simple renverra 2 pour le premier exemple, 1 pour le dernier. Ce n'est pas nécessairement faux, mais peut ne pas être le résultat souhaité non plus.

Comparaison pour l'égalité: A, А et Α se ressemblent, mais ils sont respectivement latin, cyrillique et 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 en Unicode .

paires de substitution: Celles-ci apparaissent assez souvent sur SO, je vais donc vous fournir quelques exemples de liens:

Autres?:

497
DPenner1
  • Unicode
    • est un ensemble de caractères utilisés dans le monde entier
  • UTF-8
    • un codage de caractères capable de coder tous les caractères possibles (appelés points de code) en Unicode.
    • l'unité de code est 8 bits
    • utiliser une à quatre unités de code pour coder Unicode
    • 00100100 pour " $ " (un 8 bits); 11000010 10100010 pour " ¢ " (deux 8 bits); 11100010 10000010 10101100 pour ""(trois 8 bits)
  • UTF-16
    • un autre encodage de caractères 
    • l'unité de code est 16 bits
    • utiliser une à deux unités de code pour coder Unicode
    • 00000000 00100100 pour " $ " (un 16 bits); 11011000 01010010 11011111 01100010 pour " ???? " (deux 16 bits)
55
wengeezhang

Unicode est une norme assez complexe. N'ayez pas trop peur, mais soyez préparé pour certains travaux! [2]

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

  1. Le minimum absolu que chaque développeur de logiciel a absolument, doit absolument savoir sur l’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, puis vice-président du consortium Unicode. (20 premières diapositives et vous avez terminé)

Une brève explication:

Les ordinateurs lisant des octets et les utilisateurs lisant des caractères, nous utilisons donc les normes de codage pour mapper les caractères sur des octets. ASCII a été le premier standard largement utilisé, mais ne couvre que le latin (7 bits/caractère peut représenter 128 caractères différents). Unicode est une norme dont l'objectif est de couvrir tous les caractères possibles dans le monde (peut contenir jusqu'à 1 114 112 caractères, ce qui signifie 21 bits/caractère au maximum. Current Unicode 8.0 spécifie 120 737 caractères au total, et c'est tout.).

La principale différence est qu'un caractère ASCII peut correspondre à un octet (8 bits), contrairement à la plupart des caractères Unicode. Donc, les formes/schémas d'encodage (comme UTF-8 et UTF-16) sont utilisés, et le modèle de personnage se présente comme suit:

Chaque caractère possède une position énumérée de 0 à 1 114 111 (hex: 0-10FFFF) appelée code point.
Un formulaire encoding mappe un point de code sur une séquence d'unités de code. Une unité code vous permet d'organiser les caractères en mémoire, en unités de 8 bits, en unités de 16 bits, etc. UTF-8 utilise 1 à 4 unités de 8 bits, et UTF-16 utilise 1 ou 2 unités de 16 bits, pour couvrir l’ensemble de l’Unicode de 21 bits max. Les unités utilisent des préfixes pour que les limites des caractères puissent être repérées, et davantage d'unités signifient plus de préfixes occupant des bits. Ainsi, bien que UTF-8 utilise 1 octet pour le script latin, 3 octets sont nécessaires pour les scripts ultérieurs dans le plan multilingue de base, tandis que UTF-16 utilise 2 octets pour tous ces éléments. Et c'est leur principale différence. 
Enfin, un schéma de codage (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: π
code: U + 03C0
formes de codage (unités de code):
UTF-8: CF 80
UTF-16: 03C0
schémas de codage (octets): 
UTF-8: CF 80 
UTF-16BE: 03 C0 
UTF-16LE: C0 03

Astuce: un chiffre hexadécimal représente 4 bits, donc un nombre hexadécimal à deux chiffres représente un octet
Jetez également un coup d'œil aux cartes de plans dans Wikipedia pour vous faire une idée de la disposition des jeux de caractères.

25
Neuron

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

Plus tard, la portée d'Unicode a été étendue pour inclure les caractères historiques, ce qui nécessiterait plus que les 65 536 points de code pris en charge par un codage 16 bits. Pour permettre la représentation des caractères supplémentaires sur les plates-formes qui utilisaient UCS-2, le codage 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 et de protocoles réseau anciens utilisaient des chaînes de 8 bits. UTF-8 a été conçu pour que ces systèmes puissent prendre en charge Unicode sans avoir à utiliser des caractères larges. Il est rétro-compatible avec l'ASCII 7 bits.

18
dan04

Cet article explique tous les détails http://kunststube.net/encoding/

ÉCRIRE VERS TAMPON

si vous écrivez dans un tampon de 4 octets, symbole avec encodage UTF8, votre binaire ressemblera à ceci:

00000000 11100011 10000001 10000010

si vous écrivez dans un tampon de 4 octets, symbole avec encodage UTF16, votre binaire ressemblera à ceci:

00000000 00000000 00110000 01000010

Comme vous pouvez le constater, cela affectera votre mémoire en fonction de la langue que vous utiliseriez dans votre contenu.

par exemple. Pour ce symbole particulier: Le codage UTF16 est plus efficace car nous avons 2 octets de réserve à utiliser pour le symbole suivant. Mais cela ne signifie pas que vous devez utiliser UTF16 pour l’alphabet japonais.

LECTURE À PARTIR DE TAMPON

Maintenant, si vous voulez lire les octets ci-dessus, vous devez savoir dans quel codage il a été écrit et le décoder correctement.

par exemple. Si vous décodez ceci: 00000000 11100011 10000001 10000010 En encodage UTF16, vous obtiendrez pas

Remarque: Encodage et Unicode sont deux choses différentes. Unicode est le grand (table) avec chaque symbole mappé sur un point de code unique. par exemple. Le symbole (lettre) a (code) : 30 42 (hex). Le codage, en revanche, est un algorithme qui convertit les symboles de manière plus appropriée lors du stockage sur du matériel.

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.

30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.

 enter image description here

11
InGeek

Pourquoi unicode? Parce que ASCII ne contient que 127 caractères. Ceux de 128 à 255 diffèrent d'un pays à l'autre, c'est pourquoi il existe des pages de codes. Donc, ils ont dit, laisse jusqu'à 1114111 caractères. Alors, comment stockez-vous le plus haut codepoint? Vous aurez besoin de le stocker en utilisant 21 bits, vous utiliserez donc un DWORD ayant 32 bits avec 11 bits perdus. Donc, si vous utilisez un DWORD pour stocker un caractère unicode, c'est la méthode la plus simple car la valeur de votre DWORD correspond exactement au code codé. Mais les tableaux DWORD sont bien sûr plus grands que les tableaux Word et bien sûr encore plus grands que les tableaux BYTE. C'est pourquoi il n'y a pas seulement utf-32, mais aussi utf-16. Mais utf-16 signifie un flux de mots et un mot a 16 bits. Comment le point de code le plus élevé, 1114111, peut-il s’intégrer dans un mot? Ça ne peut pas! Donc, ils ont mis tout ce qui dépasse 65535 dans un DWORD qu'ils ont appelé une paire de substitution. Ces paires de substitution sont deux mots et peuvent être détectées en regardant les 6 premiers bits. Alors qu'en est-il de l'utf-8? Il s'agit d'un tableau d'octets ou d'un flux d'octets, mais comment le point de code le plus élevé, 1114111, peut-il s'intégrer dans un octet? Ça ne peut pas! Bon, alors ils ont mis aussi un DWORD, non? Ou peut-être un mot, non? Presque juste! Ils ont inventé les séquences utf-8, ce qui signifie que chaque code supérieur à 127 doit être codé en une séquence de 2 octets, 3 octets ou 4 octets. Hou la la! Mais comment détecter de telles séquences? Eh bien, tout ce qui va jusqu’à 127 correspond à ASCII et correspond à un seul octet. Ce qui commence par 110 est une séquence de deux octets, ce qui commence par 1110 est une séquence de trois octets et ce qui commence par 11110 est une séquence de quatre octets. Les bits restants de ces "startbytes" appartiennent au point de code. Maintenant, en fonction de la séquence, les octets suivants doivent suivre. Un octet suivant commence par 10, les bits restants sont 6 bits de données utiles et appartiennent au point de code. Concaténez les bits de charge utile de startbyte et du/des octet (s) suivant (s) pour obtenir le point de code. C'est toute la magie d'utf-8. 

8
brighty

Unicode est une norme qui mappe les caractères de toutes les langues sur une valeur numérique particulière appelée Points de code. La raison en est que cela permet à différents codages d'être possibles en utilisant le même ensemble de points de code.

UTF-8 et UTF-16 sont deux de ces codages. Ils prennent des points de code en entrée et les codent en utilisant une formule bien définie pour produire la chaîne codée.

Le choix d'un encodage particulier dépend de vos besoins. Différents encodages ont des exigences de mémoire différentes et, en fonction des caractères que vous allez traiter, vous devez choisir l’encodage qui utilise le moins de séquences d’octets pour encoder ces caractères.

Pour plus de détails sur Unicode, UTF-8 et UTF-16, vous pouvez consulter cet article,

Ce que tout programmeur devrait savoir sur Unicode

7
Kishu Agarwal

UTF signifie Unicode Transformation Format (format de transformation Unicode). En gros, de nos jours, les scripts sont écrits dans des centaines d'autres langues, formats non couverts par le ASCII de base utilisé précédemment. Par conséquent, UTF est né.

UTF-8 a des capacités de codage de caractères et son unité de code est de 8 bits, alors que pour UTF-16, elle est de 16 bits. 

2
kg11

ASCII - Le logiciel n'attribue que 8 octets en mémoire pour un caractère donné. Cela fonctionne bien pour les caractères anglais et adoptés (emprunts comme la façade) car leurs valeurs décimales correspondantes sont inférieures à 128 dans la valeur décimale. Exemple de programme C.

UTF-8 - Le logiciel attribue 1 à 4 octets variables sur 8 bits pour un caractère donné. Que veut dire par variable ici? Supposons que vous envoyez le caractère 'A' via vos pages HTML dans le navigateur (HTML est UTF-8), la valeur décimale correspondante de A est 65, lorsque vous le convertissez en décimal, il devient 01000010. Cela ne nécessite qu'un octet , 1 octet de mémoire est alloué même pour des caractères anglais adoptés spéciaux, tels que "ç" dans une façade Word. Toutefois, lorsque vous souhaitez stocker des caractères européens, il nécessite 2 octets. Vous avez donc besoin de UTF-8. Toutefois, lorsque vous optez pour des caractères asiatiques, vous devez disposer d’un minimum de 2 octets et d’un maximum de 4 octets. De même, Emoji nécessite 3 à 4 octets. UTF-8 répondra à tous vos besoins.

UTF-16 allouera au minimum 2 octets et au maximum 4 octets par caractère. Il n'allouera pas 1 ou 3 octets. Chaque caractère est soit représenté en 16 bits ou 32 bits.

Alors pourquoi existe UTF-16? À l'origine, Unicode était de 16 bits et non de 8 bits. Java a adopté la version originale de UTF-16.

En résumé, vous n’avez pas besoin d’UTF-16 n’importe où, à moins qu’il ait déjà été adopté par le langage ou la plate-forme sur laquelle vous travaillez.

Le programme Java appelé par les navigateurs Web utilise UTF-16, mais le navigateur Web envoie des caractères à l'aide de UTF-8.

0
Siva