571 votes

UTF-8, UTF-16 et UTF-32

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

Je comprends qu'ils stockent tous de l'Unicode et que chacun utilise un nombre différent d'octets pour représenter un caractère. Y a-t-il un avantage à choisir l'un plutôt que l'autre ?

52 votes

Regardez cette vidéo si vous êtes intéressé par le fonctionnement de l'Unicode. youtube.com/watch?v=MijmeoH9LT4

1 votes

La vidéo se concentre sur l'UTF-8 et, effectivement, elle explique bien comment fonctionne le codage à longueur variable et est principalement compatible avec les ordinateurs qui lisent ou écrivent uniquement de l'ASCII à longueur fixe. Les responsables d'Unicode ont été intelligents lorsqu'ils ont conçu l'encodage UTF-8.

1 votes

J'ai créé un outil en ligne pour la conversion et la comparaison.

436voto

AnthonyWJones Points 122520

UTF-8 a un avantage dans le cas où les caractères ASCII représentent la majorité des caractères dans un bloc de texte, car UTF-8 les code sur 8 bits (comme ASCII). Il est également avantageux dans la mesure où un fichier UTF-8 contenant uniquement des caractères ASCII a le même encodage qu'un fichier ASCII.

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

L'UTF-32 couvre tous les caractères possibles en 4 octets. Il est donc assez volumineux. Je ne vois aucun avantage à l'utiliser.

188 votes

Avantage de l'UTF-32 : il n'est pas nécessaire de décoder les données stockées dans le point de code Unicode 32 bits pour, par exemple, les manipuler caractère par caractère. Le point de code est déjà disponible dans votre tableau/vecteur/chaîne.

0 votes

@rq : Vous avez tout à fait raison et Adam fait la même remarque. Cependant, la plupart des manipulations caractère par caractère que j'ai vues fonctionnent avec des ints courts de 16 bits et non avec un vecteur d'entiers de 32 bits. En termes de vitesse brute, certaines opérations seront plus rapides avec 32 bits.

31 votes

Il est également plus facile à analyser si (que Dieu vous vienne en aide) vous devez réimplémenter la roue.

374voto

Adam Rosenfield Points 176408

En bref :

  • UTF-8 : encodage à largeur variable, rétrocompatible avec l'ASCII. Les caractères ASCII (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. C'est bien pour les textes anglais, moins bien pour les textes asiatiques.
  • 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 les textes anglais, bon pour les textes asiatiques.
  • UTF-32 : Encodage à largeur fixe. Tous les points de code prennent quatre octets. C'est un énorme gouffre à mémoire, mais il est rapide à utiliser. Rarement utilisé.

En long : voir Wikipédia : UTF-8 , UTF-16 y UTF-32 .

4 votes

La raison pour laquelle l'UTF-16 fonctionne est que U+D800-U+DFFF sont laissés en blanc dans le BMP pour les paires de substituts. C'est astucieux.

68 votes

@spurrymoses : Je me réfère strictement à l'espace occupé par les octets de données. L'UTF-8 nécessite 3 octets par caractère asiatique, alors que l'UTF-16 ne nécessite que 2 octets par caractère asiatique. Ce n'est pas vraiment un problème majeur, car les ordinateurs disposent aujourd'hui de tonnes de mémoire par rapport à la quantité moyenne de texte stockée dans la mémoire d'un programme.

13 votes

UTF-32 n'est plus rarement utilisé... sous osx et linux wchar_t La valeur par défaut est de 4 octets. gcc dispose d'une option -fshort-wchar qui réduit la taille à 2 octets, mais rompt la compatibilité binaire avec les librairies std.

137voto

Quassnoi Points 191041
  • UTF-8 est variable 1 à 4 des octets.

  • UTF-16 est variable 2 ou 4 des octets.

  • UTF-32 est corrigé 4 des octets.

42 votes

UTF8 est en fait composé de 1 à 6 octets.

7 votes

@Urkle est techniquement correct parce que le mappage de la gamme complète d'UTF32/LE/BE inclut U-00200000 - U-7FFFFFFF même si Unicode v6.3 se termine à U-0010FFFF inclus. Voici une bonne description de la façon d'encoder/découper 5 et 6 octets en utf8 : lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html

4 votes

En les étayant par des références pertinentes et leurs sources ?

94voto

jalf Points 142628

Unicode définit un immense jeu de caractères unique, attribuant une valeur entière unique à chaque symbole graphique (il s'agit d'une simplification majeure, qui n'est pas réellement vraie, mais qui est suffisamment proche pour les besoins de cette question). UTF-8/16/32 sont simplement des façons différentes d'encoder cela.

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

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

L'UTF-8 utilise des valeurs de 8 bits par défaut, ce qui signifie que les 127 premières valeurs sont des caractères d'un octet de largeur fixe (le bit le plus significatif est utilisé pour indiquer qu'il s'agit du début d'une séquence de plusieurs octets, ce qui laisse 7 bits pour la valeur réelle du caractère). Tous les autres caractères sont encodés comme des séquences de 4 octets maximum (si ma mémoire est bonne).

Cela nous amène à parler des avantages. Tous les caractères ASCII sont directement compatibles avec l'UTF-8, de sorte que pour la mise à jour des applications existantes, l'UTF-8 est un choix courant et évident. Dans presque tous les cas, c'est aussi celui qui utilise le moins de mémoire. D'un autre côté, vous ne pouvez pas garantir la largeur d'un caractère. Il peut avoir une largeur de 1, 2, 3 ou 4 caractères, ce qui complique la manipulation des chaînes de caractères.

UTF-32 est à l'opposé, il utilise le plus de mémoire (chaque caractère a une largeur fixe de 4 octets), mais d'un autre côté, vous pouvez conozca que chaque caractère a cette longueur précise, ce qui simplifie grandement la manipulation des chaînes de caractères. Vous pouvez calculer le nombre de caractères d'une chaîne simplement à partir de sa longueur en octets. Ce n'est pas possible avec l'UTF-8.

L'UTF-16 est un compromis. Il permet à le plus tiennent dans une valeur de 16 bits de largeur fixe. Ainsi, tant que vous n'avez pas de symboles chinois, de notes de musique ou autres, vous pouvez supposer que chaque caractère a une largeur de 16 bits. Il utilise moins de mémoire que l'UTF-32. Mais c'est en quelque sorte "le pire des deux mondes". Il utilise presque toujours plus de mémoire que l'UTF-8 et n'évite toujours pas le problème qui affecte l'UTF-8 (caractères de longueur variable).

Enfin, il est souvent utile de se contenter de ce que la plateforme prend en charge. Windows utilise UTF-16 en interne, c'est donc le choix le plus évident.

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

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

14 votes

Il est inexact de dire qu'Unicode attribue un nombre entier unique à chaque symbole graphique . Il attribue un tel à chaque point de code, mais certains points de code sont des points de code. caractères de contrôle invisibles et certains symboles graphiques requièrent points de code multiples à représenter.

18 votes

@tchrist : oui, c'est inexact. Le problème est que pour expliquer correctement Unicode, il faut écrire des milliers de pages. J'espérais faire passer le concept de base pour expliquer la différence entre les encodages

0 votes

@jalf lol c'est vrai donc en gros pour expliquer l'Unicode il faudrait écrire la phrase Spécification de base de l'Unicode

52voto

rook Points 1251

Unicode est une norme et environ UTF-x vous pouvez considérer qu'il s'agit d'une mise en œuvre technique à des fins pratiques :

  • UTF-8 - " taille optimisée " : mieux adapté aux données basées sur des caractères latins (ou ASCII), il ne prend qu'un octet par caractère mais la taille augmente en fonction de la variété des symboles (et dans le pire des cas peut atteindre 6 octets par caractère).
  • UTF-16 - " équilibre " : il faut au moins 2 octets par caractère, ce qui est suffisant pour l'ensemble des langues courantes, avec une taille fixe pour faciliter la manipulation des caractères (mais la taille reste variable et peut atteindre 4 octets par caractère).
  • UTF-32 - " performance " : permet l'utilisation d'algorithmes simples grâce à des caractères de taille fixe (4 octets), mais présente des inconvénients en termes de mémoire.

0 votes

Les "langues courantes" ne sont pas si courantes que cela dans de nombreuses parties du monde ^^

3 votes

UTF-16 est en fait optimisé pour les caractères non ASCII. Cela dépend donc des langues dans lesquelles il sera utilisé.

0 votes

@tuxayo tout à fait d'accord, il est intéressant de noter les ensembles de caractères Hanzi et Kanji pour la partie asiatique du monde.

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