web-dev-qa-db-fra.com

UTF-8, UTF-16 et UTF-32

Quelles sont les différences entre UTF-8, UTF-16 et UTF-32?

Je comprends qu’ils vont tous stocker l’Unicode et que chacun utilise un nombre différent d’octets pour représenter un caractère. Y at-il un avantage à choisir l’un sur l’autre?

450
Joe

UTF-8 présente un avantage dans le cas où ASCII caractères représentent la majorité des caractères d'un bloc de texte, car UTF-8 code tous les caractères sur 8 bits (comme l'ASCII). En outre, un fichier UTF-8 contenant uniquement ASCII caractères a le même encodage qu'un fichier ASCII.

UTF-16 est préférable où ASCII n'est pas prédominant, car il utilise principalement 2 octets par caractère. UTF-8 commencera à utiliser 3 octets ou plus pour les caractères d’ordre supérieur, tandis que UTF-16 ne conserve que 2 octets pour la plupart des caractères.

UTF-32 couvrira tous les caractères possibles sur 4 octets. Cela le rend assez gonflé. Je ne vois aucun avantage à l'utiliser.

339
AnthonyWJones

En bref:

  • UTF-8: Encodage à largeur variable, rétrocompatible avec ASCII. ASCII caractères (U + 0000 à U + 007F) prennent 1 octet, les points de code U + 0080 à U + 07FF prennent 2 octets, les points de code U + 0800 à U + FFFF prennent 3 octets, les points de code U +10000 à U + 10FFFF prennent 4 octets. Bon pour le texte anglais, pas si bon pour le texte asiatique.
  • UTF-16: Encodage à largeur variable. Les points de code U + 0000 à U + FFFF prennent 2 octets, les points de code U + 10000 à U + 10FFFF prennent 4 octets. Mauvais pour le texte anglais, bon pour le texte asiatique.
  • UTF-32: Encodage à largeur fixe. Tous les points de code prennent quatre octets. Une énorme mémoire, mais rapide à utiliser. Rarement utilisé.

En long: voir Wikipedia: TF-8 , TF-16 , et TF-32 .

299
Adam Rosenfield
  • UTF-8 est une variable 1 à 4 octets.

  • UTF-16 est variable 2 ou 4 octets.

  • UTF-32 est fixe 4 octets.

108
Quassnoi

Unicode définit un seul jeu de caractères énorme, attribuant une valeur entière unique à chaque symbole graphique (simplification majeure, ce n'est pas vrai, mais c'est assez proche pour les besoins de cette question). UTF-8/16/32 sont simplement différentes manières de coder cela.

En bref, UTF-32 utilise des valeurs 32 bits pour chaque caractère. Cela leur permet d'utiliser un code à largeur fixe pour chaque caractère.

UTF-16 utilise 16 bits par défaut, mais cela ne vous donne que 65 000 caractères possibles, ce qui est loin d'être suffisant pour le jeu complet Unicode. Certains caractères utilisent donc des paires de valeurs 16 bits.

Et UTF-8 utilise les valeurs 8 bits par défaut, ce qui signifie que les 127 premières valeurs sont des caractères à octet unique de largeur fixe (le bit le plus significatif est utilisé pour indiquer qu'il s'agit du début d'une séquence multi-octets, en laissant 7 bits pour la valeur de caractère réelle). Tous les autres caractères sont codés sous forme de séquences de 4 octets maximum (si la mémoire le permet).

Et cela nous mène aux avantages. Tous les caractères ASCII sont directement compatibles avec UTF-8. UTF-8 est donc un choix courant et évident pour la mise à niveau d'applications existantes. Dans presque tous les cas, il utilisera également le moins de mémoire. D'autre part, vous ne pouvez faire aucune garantie quant à la largeur d'un caractère. Il peut contenir 1, 2, 3 ou 4 caractères, ce qui rend difficile la manipulation des chaînes.

UTF-32 est opposé, il utilise le plus de mémoire (chaque caractère a une largeur fixe de 4 octets), mais par contre, vous savez que chaque caractère a cette longueur précise, la manipulation de chaîne devient donc très difficile plus simple. Vous pouvez calculer le nombre de caractères dans une chaîne simplement à partir de la longueur en octets de la chaîne. Vous ne pouvez pas faire cela avec UTF-8.

UTF-16 est un compromis. Il laisse la plupart caractères s’intégrer dans une valeur 16 bits à largeur fixe. Donc, tant que vous n'avez pas de symboles chinois, de notes de musique ou d'autres, vous pouvez supposer que chaque caractère a une largeur de 16 bits. Il utilise moins de mémoire que UTF-32. Mais c'est à certains égards "le pire des deux mondes". Il utilise presque toujours plus de mémoire que UTF-8, et il n'empêche pas le problème qui affecte UTF-8 (caractères de longueur variable).

Enfin, il est souvent utile d’utiliser uniquement ce que la plate-forme prend en charge. Windows utilise UTF-16 en interne, donc sur Windows, c'est le choix évident.

Linux varie un peu, mais ils utilisent généralement UTF-8 pour tout ce qui est compatible Unicode.

Réponse courte: les trois codages peuvent coder le même jeu de caractères, mais ils représentent chaque caractère sous forme de séquences d'octets différentes.

74
jalf

Unicode est un standard et à propos de UTF-x peut être considéré comme un mise en œuvre technique à des fins pratiques:

  • TF-8 - "taille optimisée": idéal pour les données basées sur des caractères latins (ou ASCII), il ne prend qu'un octet par caractère, mais sa taille augmente en conséquence et dans le pire des cas pourrait atteindre 6 octets par caractère)
  • TF-16 - "balance": il faut un minimum de 2 octets par caractère, ce qui est suffisant pour un ensemble existant des langues courantes avec une taille fixe pour faciliter le traitement des caractères ( mais la taille est toujours variable et peut atteindre 4 octets par caractère)
  • TF-32 - "performance": permet d'utiliser des algorithmes simples comme résultat de caractères de taille fixe (4 octets) mais avec un inconvénient mémoire.
41
rook

J'ai essayé de donner une explication simple dans mon blogpost .

UTF-32

nécessite 32 bits (4 octets) pour coder tout caractère . Par exemple, pour représenter le point de code de caractère "A" à l'aide de ce schéma, vous devez écrire 65 en nombre binaire 32 bits:

00000000 00000000 00000000 01000001 (Big Endian)

Si vous examinez de plus près, vous remarquerez que les sept bits les plus à droite sont en fait les mêmes lorsque vous utilisez le schéma ASCII. Mais comme UTF-32 est un schéma de largeur fixe , nous devons associer trois octets supplémentaires. Ce qui signifie que si nous avons deux fichiers ne contenant que le caractère "A", l'un est codé en ASCII et l'autre en UTF-32, leur taille sera de 1 octet et de 4 octets en conséquence.

UTF-16

Beaucoup de gens pensent que, comme UTF-32 utilise une largeur fixe de 32 bits pour représenter un point de code, l'UTF-16 a une largeur fixe de 16 bits. FAUX!

En UTF-16, le point de code peut être représenté sur 16 bits, OR 32 bits. Donc, ce schéma est un système de codage à longueur variable. Quel est l'avantage sur l'UTF-32? Au moins pour ASCII, la taille des fichiers ne sera pas 4 fois supérieure à l'original (mais deux fois), nous ne sommes donc toujours pas compatibles avec la version précédenteASCII.

Puisque 7 bits suffisent pour représenter le caractère "A", nous pouvons maintenant utiliser 2 octets au lieu de 4 comme pour l'UTF-32. Ça va ressembler à:

00000000 01000001

UTF-8

Vous avez bien deviné. Dans UTF-8, le point de code peut être représenté en 32, 16, 24 ou 8 bits. En tant que système UTF-16, il s'agit également d'un système de codage à longueur variable.

Enfin, nous pouvons représenter "A" de la même manière que nous le représentons en utilisant le système de codage ASCII:

01001101

Un petit exemple où UTF-16 est réellement meilleur que UTF-8:

Considérez la lettre chinoise "" - son codage UTF-8 est:

11101000 10101010 10011110

Bien que son encodage UTF-16 soit plus court:

10001010 10011110

Afin de comprendre la représentation et son interprétation, visitez le message d'origine.

22
Maroun

UTF-8

  • n'a pas de concept d'ordre byte
  • utilise entre 1 et 4 octets par caractère
  • ASCII est un sous-ensemble compatible de codage
  • complètement auto-synchronisant, par ex. un octet déposé de n'importe où dans un flux corrompra au plus un seul caractère
  • à peu près toutes les langues européennes sont codées en deux octets ou moins par caractère

UTF-16

  • doit être analysé avec l'ordre d'octet connu ou en lisant une marque d'ordre d'octet (BOM)
  • utilise 2 ou 4 octets par caractère

UTF-32

  • chaque caractère est de 4 octets
  • doit être analysé avec l'ordre d'octet connu ou en lisant une marque d'ordre d'octet (BOM)

UTF-8 sera le plus économe en espace sauf si la majorité des caractères proviennent de l'espace de caractères CJK (chinois, japonais et coréen).

UTF-32 est le meilleur pour un accès aléatoire par décalage de caractère dans un tableau d'octets.

19
Jeff Adamson

En UTF-32, tous les caractères sont codés sur 32 bits. L'avantage est que vous pouvez facilement calculer la longueur de la chaîne. L'inconvénient est que, pour chaque ASCII caractères, vous perdez trois octets supplémentaires.

En UTF-8, les caractères ont une longueur variable, les caractères ASCII sont codés sur un octet (huit bits), la plupart des caractères spéciaux occidentaux sont codés sur deux octets ou sur trois octets (par exemple, € correspond à trois octets), et les caractères plus exotiques peuvent prendre jusqu'à quatre octets. Le désavantage évident est qu’à priori, vous ne pouvez pas calculer la longueur de la chaîne. Mais il faut beaucoup moins d'octets pour coder du texte en alphabet latin (anglais) par rapport à UTF-32.

UTF-16 est également de longueur variable. Les caractères sont codés sur deux ou quatre octets. Je ne vois vraiment pas le point. Il a le désavantage d’être de longueur variable, mais n’a pas l’avantage d’économiser autant d’espace que le format UTF-8.

Parmi ces trois, UTF-8 est clairement le plus répandu.

13
vartec

J'ai fait quelques tests pour comparer les performances de base de données entre UTF-8 et UTF-16 dans MySQL.

Mise à jour des vitesses

UTF-8

Enter image description here

UTF-16

Enter image description here

Vitesses d'insertion

Enter image description here

Enter image description here

Supprimer les vitesses

Enter image description here

Enter image description here

13
Farid Movsumov

En fonction de votre environnement de développement, vous pouvez même ne pas avoir le choix du type de codage que votre type de données de chaîne utilisera en interne.

Mais pour stocker et échanger des données, j'utiliserais toujours UTF-8, si vous avez le choix. Si vous avez principalement ASCII données, cela vous donnera la plus petite quantité de données à transférer, tout en étant capable de tout encoder. Optimisation pour le moins d'E/S est la voie à suivre sur les machines modernes.

6
mghie

Comme mentionné précédemment, la différence réside principalement dans la taille des variables sous-jacentes, qui deviennent chaque fois plus grandes pour permettre à davantage de caractères d'être représentés.

Cependant, les polices, l’encodage et les choses sont terriblement compliqués (inutilement?), Un grand lien est donc nécessaire pour préciser davantage:

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

Ne vous attendez pas à tout comprendre, mais si vous ne voulez pas avoir de problèmes plus tard, cela vaut la peine d'en apprendre le plus possible, le plus tôt possible (ou tout simplement de demander à quelqu'un d'autre de le résoudre pour vous).

Paul.

2
Paul W Homer

En bref, la seule raison d'utiliser UTF-16 ou UTF-32 est de prendre en charge les scripts non anglais et anciens, respectivement.

Je me demandais pourquoi quelqu'un choisirait un encodage non-UTF-8 alors que c'est évidemment plus efficace pour le Web/la programmation.

Une idée fausse commune - le nombre suffixé n'est pas une indication de sa capacité. Ils prennent tous en charge l’Unicode complet, mais UTF-8 peut gérer ASCII avec un seul octet. Il est donc PLUS efficace/moins corrompu par la CPU et sur Internet.

Bonne lecture: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html et http://utf8everywhere.org =

0
killjoy