52 votes

Les UTF-8, UTF-16 et UTF-32 diffèrent-ils par le nombre de caractères qu'ils peuvent stocker ?

Ok. Je sais que ça ressemble au typique "Pourquoi n'a-t-il pas simplement cherché sur Google ou sur le site de www.unicode.org et le regarder ?" mais pour une question aussi simple, la réponse m'échappe toujours après avoir vérifié les deux sources.

Je suis pratiquement sûr que ces trois systèmes d'encodage prennent en charge tous les caractères Unicode, mais je dois le confirmer avant de faire cette affirmation dans une présentation.

Question bonus : Ces codages diffèrent-ils par le nombre de caractères qu'ils peuvent prendre en charge ?

66voto

Artelius Points 25772

Il n'existe pas de caractère Unicode qui puisse être stocké dans un encodage mais pas dans un autre. C'est simplement parce que les caractères Unicode valides ont été limités à ce qui peut être stocké dans UTF-16 (qui a la plus petite capacité des trois encodages). En d'autres termes, l'UTF-8 et l'UTF-32 ne sont pas compatibles. pourrait peuvent être utilisés pour représenter une gamme plus large de caractères que l'UTF-16, mais ils ne sont pas . Lisez la suite pour plus de détails.

UTF-8

UTF-8 est un code à longueur variable. Certains caractères nécessitent un octet, d'autres deux, d'autres encore trois ou quatre. Les octets de chaque caractère sont simplement écrits les uns après les autres comme un flux continu d'octets.

Alors que certains caractères UTF-8 peuvent avoir une longueur de 4 octets, UTF-8 ne peut pas coder 2^32 caractères . C'est loin d'être le cas. Je vais essayer d'en expliquer les raisons.

Le logiciel qui lit un flux UTF-8 reçoit simplement une séquence d'octets - comment est-il censé décider si les 4 octets suivants sont un seul caractère de 4 octets, ou deux caractères de 2 octets, ou quatre caractères de 1 octet (ou une autre combinaison) ? En gros, cela se fait en décidant que certaines séquences de 1 octet ne sont pas des caractères valides, que certaines séquences de 2 octets ne sont pas des caractères valides, et ainsi de suite. Lorsque ces séquences non valides apparaissent, il est supposé qu'elles font partie d'un plus longtemps séquence.

Je suis sûr que vous avez déjà vu un autre exemple de ce phénomène : il s'agit de l'échappement. Dans de nombreux langages de programmation, il est décidé que le \ dans le code source d'une chaîne ne se traduit pas par un caractère valide dans la forme "compilée" de la chaîne. Lorsqu'un tel caractère est trouvé dans le code source, il est supposé faire partie d'une séquence plus longue, comme par exemple \n o \xFF . Notez que \x est une séquence de 2 caractères non valide, et \xF est une séquence de 3 caractères non valide, mais \xFF est une séquence valide de 4 caractères.

Fondamentalement, il y a un compromis entre avoir beaucoup de caractères et avoir des caractères plus courts. Si vous voulez 2^32 caractères, ils doivent avoir une longueur moyenne de 4 octets. Si vous voulez que tous vos caractères soient de 2 octets ou moins, alors vous ne pouvez pas avoir plus de 2^16 caractères. UTF-8 offre un compromis raisonnable : tous les caractères ASCII (ASCII 0 à 127) sont représentés sur un octet, ce qui est très bien pour la compatibilité, mais beaucoup plus de caractères sont autorisés.

Comme la plupart des codages à longueur variable, y compris les types de séquences d'échappement présentés ci-dessus, UTF-8 est un code instantané . Cela signifie que le décodeur lit simplement octet par octet et que, dès qu'il atteint le dernier octet d'un caractère, il sait de quoi il s'agit (et il sait qu'il s'agit de l'octet le plus proche). n'est pas le début d'un caractère plus long).

Par exemple, le caractère "A" est représenté par l'octet 65, et il n'existe pas de caractères de deux/trois/quatre octets dont le premier octet est 65. Sinon, le décodeur ne serait pas en mesure de distinguer ces caractères d'un "A" suivi d'autre chose.

Mais UTF-8 est encore plus limité. Il garantit que l'encodage d'un caractère plus court n'apparaîtra jamais partout dans l'encodage d'un caractère plus long. Par exemple, aucun des octets d'un caractère de 4 octets ne peut être 65.

Étant donné que l'UTF-8 compte 128 caractères différents de 1 octet (dont la valeur des octets est comprise entre 0 et 127), tous les caractères de 2, 3 et 4 octets doivent être composés uniquement d'octets compris entre 128 et 256. C'est une restriction importante. Cependant, elle permet aux fonctions de chaîne de caractères orientées octet de fonctionner avec peu ou pas de modifications. Par exemple, la fonction C strstr() fonctionne toujours comme prévu si ses entrées sont des chaînes UTF-8 valides.

UTF-16

L'UTF-16 est également un code à longueur variable ; ses caractères consomment soit 2 soit 4 octets. Les valeurs de 2 octets dans la plage 0xD800-0xDFFF sont réservées à la construction de caractères de 4 octets, et tous les caractères de 4 octets sont constitués de deux octets dans la plage 0xD800-0xDBFF suivis de 2 octets dans la plage 0xDC00-0xDFFF. Pour cette raison, Unicode n'attribue aucun caractère dans la plage U+D800-U+DFFF.

UTF-32

L'UTF-32 est un code à longueur fixe, chaque caractère ayant une longueur de 4 octets. Bien que cela permette l'encodage de 2^32 caractères différents, seules les valeurs comprises entre 0 et 0x10FFFF sont autorisées dans ce schéma.

Comparaison des capacités :

  • UTF-8 : 2 097 152 (en réalité 2 166 912, mais en raison de détails de conception, certains d'entre eux correspondent à la même chose)
  • UTF-16 : 1,112,064
  • UTF-32 : 4.294.967.296 (mais limité aux 1.114.112 premiers)

Le plus restreint est donc UTF-16 ! La définition formelle d'Unicode a limité les caractères Unicode à ceux qui peuvent être encodés avec UTF-16 (c'est-à-dire la plage U+0000 à U+10FFFF, à l'exclusion de U+D800 à U+DFFF). UTF-8 et UTF-32 supportent tous ces caractères.

Le système UTF-8 est en fait "artificiellement" limité à 4 octets. Il peut être étendu à 8 octets sans violer les restrictions que j'ai décrites précédemment, et cela donnerait une capacité de 2^42. La spécification originale de l'UTF-8 autorisait en fait jusqu'à 6 octets, ce qui donne une capacité de 2^31. Mais RFC 3629 l'a limité à 4 octets, puisque c'est la quantité nécessaire pour couvrir tout ce que fait l'UTF-16.

Il existe d'autres schémas d'encodage Unicode (principalement historiques), notamment UCS-2 (qui n'est capable d'encoder que de U+0000 à U+FFFF).

0 votes

Quelle est la RFC pour l'UTF-8 original ?

4 votes

La réponse correcte marquée semble être carrément fausse Cette réponse donne effectivement des chiffres et est très complète dans son explication. Réponse géniale +1

0 votes

UTF-8 ne peut pas encoder 2^32 caractères. C'est loin d'être le cas. Notez que l'ancien encodage supportait (comme vous le montrez) environ 2^31 ce qui n'est pas proche si l'on considère que 2 milliards c'est beaucoup, mais une différence de x2 est assez proche en termes de logiciel informatique....

45voto

skoob Points 1066

Non, il s'agit simplement de méthodes d'encodage différentes. Ils prennent tous en charge l'encodage du même ensemble de caractères.

UTF-8 utilise entre un et quatre octets par caractère, selon le caractère que vous codez. Les caractères de la gamme ASCII ne prennent qu'un seul octet, tandis que les caractères très inhabituels en prennent quatre.

L'UTF-32 utilise quatre octets par caractère, quel que soit le caractère en question. Il utilisera donc toujours plus d'espace que l'UTF-8 pour coder la même chaîne. Le seul avantage est que vous pouvez calculer le nombre de caractères d'une chaîne UTF-32 en comptant uniquement les octets.

L'UTF-16 utilise deux octets pour la plupart des caractères, quatre octets pour les caractères inhabituels.

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

4 votes

"donc il utilisera toujours plus d'espace que l'UTF-8" -- vous voulez dire plus d'espace ou un espace égal.

1 votes

Et l'espace est de moins en moins cher. l'espace supplémentaire utilisé par l'utf-32 n'est donc pas important. de plus, pour trouver le nième caractère dans l'utf-8, il faut O(n), mais dans l'utf-32, il faut seulement O(1), ce qui est beaucoup plus rapide !

5 votes

Légèrement incorrect - UTF-8 utilise n'importe où entre un et six octets par caractère, selon le caractère que vous encodez.

7voto

Derek Park Points 25025

UTF-8, UTF-16 et UTF-32 prennent tous en charge l'ensemble des points de code Unicode. Il n'y a pas de caractères qui sont supportés par l'un mais pas par l'autre.

Quant à la question bonus "Ces codages diffèrent-ils dans le nombre de caractères qu'ils peuvent prendre en charge ?". Oui et non. La façon dont UTF-8 et UTF-16 sont encodés limite le nombre total de points de code qu'ils peuvent supporter à moins de 2^32. Cependant, le Consortium Unicode n'ajoutera pas à UTF-32 des points de code qui ne peuvent pas être représentés dans UTF-8 ou UTF-16. Cela violerait l'esprit des normes d'encodage et rendrait impossible de garantir une correspondance biunivoque entre UTF-32 et UTF-8 (ou UTF-16).

0 votes

Je crois savoir qu'il existe des moyens d'étendre l'UTF-8 pour qu'il prenne entièrement en charge les 32 bits. Avec l'UTF-16, la limite de U+10FFFF est câblée et ne peut être dépassée sans changer complètement la façon dont les paires de substituts fonctionnent.

0 votes

À l'origine, il pouvait couvrir 31 bits. C'est le maximum que le schéma de codage peut gérer. (Il a depuis été révisé pour ne couvrir que les points de code Unicode, soit beaucoup moins que 31 bits).

0 votes

Plus précisément, la spécification originale de l'UTF-8 autorisait 31 bits, mais a ensuite été limitée par la RFC 3629 à 21 bits (avec le point de code le plus élevé limité à U+10FFFF au lieu de U+1FFFFF) pour maintenir une compatibilité totale avec l'encodage UTF-16, et non avec Unicode lui-même.

5voto

Atanas Korchev Points 20945

Personnellement, je vérifie toujours Le message de Joel sur l'unicode, les encodages et les jeux de caractères en cas de doute.

2 votes

Pourquoi ne pas consulter plutôt unicode.org, qui a l'avantage d'être correct sur certains points.

0 votes

L'article de Joel n'est pas destiné à servir de référence pour l'unicode, les encodages, les jeux de caractères ou tout autre élément de ce genre. Il s'agit plutôt d'une publication indiquant ce que vous devez être conscient de.

0 votes

@JonHanna pouvez-vous préciser quelle partie du message de Joel est incorrecte ?

4voto

Robert Paulson Points 10792

Tous les codages UTF-8/16/32 peuvent représenter tous les caractères Unicode. Voir Comparaison des encodages Unicode sur Wikipedia .

Cet article d'IBM Encodez vos documents XML en UTF-8 est très utile, et indique que si vous avez le choix, il est préférable de choisir UTF-8. Les raisons principales sont un large support des outils, et UTF-8 peut généralement passent par des systèmes qui ne connaissent pas l'unicode.

De la section Ce que disent les spécifications dans le Article d'IBM :

Le W3C et l'IETF ont tous deux sont récemment devenus plus intransigeants sur de choisir UTF-8 en premier, en dernier, et parfois seulement. Le modèle de caractères du W3C Modèle de caractères pour le World Wide Web 1.0 : Fundamentals du W3C stipule : "Lorsqu'un caractère unique unique est requis, le codage de le codage des caractères DOIT être UTF-8, UTF-16 ou UTF-32. L'US-ASCII est compatible à la hausse avec UTF-8 (une chaîne US-ASCII est également une chaîne UTF-8 une chaîne UTF-8, voir [RFC 3629]), et UTF-8 est donc donc approprié si la compatibilité avec US-ASCII est souhaitée." Dans la pratique, pratique, la compatibilité avec US-ASCII est si utile que c'est presque une une exigence. Le W3C explique judicieusement , "Dans d'autres situations, comme pour les APIs, UTF-16 ou UTF-32 peuvent être plus approprié. Les raisons possibles pour de choisir l'un d'entre eux sont l'efficacité du traitement interne et l'interopérabilité avec d'autres processus".

0 votes

Les urls d'IBM sont cassées, je pense que c'est censé être un lien vers ibm.com/developerworks/xml/library/x-utf8

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