Est-ce que UTF-8, UTF-16 et UTF-32 diffèrent dans le nombre de caractères qu'ils peuvent stocker?
OK. Je sais que cela ressemble à la typique " pourquoi n'a-t-il pas simplement Google ou aller à www.unicode.org et le chercher?" question, mais pour une question aussi simple la réponse m'échappe toujours après avoir vérifié les deux sources.
je suis assez sûr que les trois systèmes d'encodage supportent tous les caractères Unicode, mais je dois le confirmer avant de faire cette réclamation dans une présentation.
Question Bonus: ces encodages diffèrent-ils dans le nombre de caractères qu'ils peuvent être étendus pour supporter?
6 réponses
Non, Ce sont simplement des 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 encodez. Les caractères dans la gamme ASCII ne prennent qu'un octet tandis que les caractères très inhabituels en prennent quatre.
UTF-32 utilise quatre octets par caractère quel que soit le caractère qu'il est, de sorte qu'il utilisera toujours plus D'espace que UTF-8 pour encoder le même chaîne. Le seul avantage est que vous pouvez calculer le nombre de caractères dans une chaîne UTF-32 en ne comptant que les octets.
UTF-16 utilise deux octets pour la plupart des caractères, quatre octets pour les inhabituels.
http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings
il n'y a 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, UTF-8 et et UTF-32 pourraient être utilisés pour représenter une gamme plus large de caractères que UTF-16, mais ils ne sont pas . Lire la suite pour plus de détails.
UTF-8
UTF-8 est un code de longueur variable. Certains caractères requièrent 1 octet, d'autres 2, 3 et 4. Les octets pour chaque caractère sont simplement écrits l'un après l'autre comme un flux continu d'octets.
alors que certains caractères UTF-8 peuvent avoir 4 octets de long, UTF-8 ne peut pas encoder 2^32 caractères . Il n'est même pas proche. Je vais essayer d'expliquer les raisons pour cela.
le logiciel qui lit un flux UTF-8 juste une séquence d'octets comment est-il censé décider si les 4 octets est un simple 4-byte character, ou deux caractères de 2 octets, ou quatre personnages 1 octet (ou une combinaison)? Fondamentalement, ceci est fait en décidant que certaines séquences d'un octet ne sont pas des caractères valides, et certaines séquences de deux octets ne sont pas des caractères valides, et ainsi de suite. Lorsque ces séquences non valides apparaissent, on suppose qu'elles font partie d'une séquence plus longue .
Vous avez vu un exemple assez différent de cela, je suis sûr: il s'appelle s'échapper. Dans de nombreux langages de programmation, il est décidé que le caractère \
du 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 \ est trouvé dans la source, il est supposé faire partie d'une séquence plus longue, comme \n
ou \xFF
. Notez que \x
n'est pas valide 2-séquence de caractères, et \xF
n'est pas valide 3-séquence de caractères, mais \xFF
est une séquence valide de 4 caractères.
en gros, 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 être en moyenne 4 octets de long. Si vous souhaitez que tous vos caractères à 2 octets ou moins, alors vous ne pouvez pas avoir plus de 2^16 caractères. UTF-8 donne un compromis raisonnable: tous les caractères ASCII (ASCII 0 à 127) sont donnés des représentations d'un octet, ce qui est grand pour la compatibilité, mais beaucoup plus de caractères sont autorisés.
comme la plupart des codages de 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 se contente de lire octet par octet, et dès qu'il atteint le dernier octet d'un caractère, il sait ce que le personnage est (et il sait qu'il n'est pas le début d'un long personnage).
pour par exemple, le caractère " A " est représenté à l'aide du byte 65, et il n'y a pas de caractères à deux/trois/quatre octets dont le premier est 65. Sinon, le décodeur ne pourrait pas distinguer ces personnages à part un " A " suivi d'autre chose.
mais L'UTF-8 est encore plus restreint. Il garantit que le codage d'un caractère plus court n'apparaît jamais n'importe où dans le codage d'un caractère plus long. Par exemple, aucun des octets 4 octets le caractère peut être 65.
étant donné que L'UTF-8 comporte 128 caractères différents de 1 octet (dont les valeurs de byte sont 0-127), les caractères de 2, 3 et 4 octets doivent être composés uniquement d'octets se situant entre 128-256. C'est une grosse restriction. Cependant, il permet aux fonctions de chaîne orientées byte de fonctionner avec peu ou pas de modification. Par exemple, la fonction strstr()
de C fonctionne toujours comme prévu si ses entrées sont des chaînes UTF-8 valides.
UTF-16
UTF-16 est aussi un code de longueur variable; ses caractères consomment soit 2 ou 4 octets. Les valeurs de 2 octets dans l'intervalle 0xD800-0xDFFF sont réservées à la construction de caractères de 4 octets, et tous les caractères de 4 octets se composent de deux octets dans l'intervalle 0xD800-0xDBFF suivi de 2 octets dans l'intervalle 0xDC00-0xDFFF. Pour cette raison, Unicode n'attribue aucun caractère dans la gamme U+D800-U+DFFF.
UTF-32
UTF-32 est une longueur fixe code, avec chaque caractère de 4 octets de long. Alors que cela permet l'encodage de 2^32 caractères différents, seules les valeurs entre 0 et 0x10FFFF sont autorisées dans ce schéma.
comparaison de capacité:
- UTF-8: 2,097,152 (en fait 2,166,912 mais en raison de détails de conception certains d'entre eux carte à la même chose)
- UTF-16: 1,112,064
- UTF-32: 4,294,967,296 (mais limité à la première 1,114,112)
le plus restreint est donc UTF-16! La définition Unicode formelle a limité les caractères Unicode à ceux qui peuvent être encodés avec UTF-16 (i.e. la plage U+0000 à U+10FFF excluant 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 plus haut, ce qui donnerait une capacité de 2^42. La spécification initiale UTF-8 permettait en fait jusqu'à 6 octets, ce qui donne une capacité de 2^31. Mais RFC 3629 limité à 4 octets, car c'est combien est nécessaire pour couvrir tout ce que L'UTF-16 fait.
il existe d'autres systèmes D'encodage Unicode (principalement historiques), notamment UCS-2 (qui n'est capable d'encoder U+0000 que pour U+FFFF).
UTF-8, UTF-16 et UTF-32 supportent tous 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 "est-ce que ces encodages diffèrent dans le nombre de caractères qu'ils peuvent être étendus pour supporter?"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 de points de code à UTF-32 qui ne peut être représenté en UTF-8 ou UTF-16. Cela violerait l'esprit des normes d'encodage et rendrait impossible la garantie d'une correspondance un-à-un entre UTF-32 et UTF-8 (ou UTF-16).
personnellement, je vérifie toujours Joel's post sur unicode, encodages et jeux de caractères en cas de doute.
tous les codages UTF-8/16/32 peuvent cartographier tous les caractères Unicode. Voir comparaison de Wikipedia des encodages Unicode .
cet article D'IBM code vos documents XML dans UTF-8 est très utile, et indique si vous avez le choix, il est préférable de choisir UTF-8. Principalement les raisons sont large soutien d'outil, et UTF-8 peut généralement passer par des systèmes qui ne sont pas au courant de unicode.
De la section Ce que les spécifications dire dans le IBM article :
le W3C et L'IETF ont récemment devenu plus catégorique sur choisir UTF-8 en premier, en dernier, et parfois seulement. Le caractère du W3C Modèle pour le World Wide Web 1.0: Les fondamentaux des etats, "Lors de un unique l'encodage des caractères est requis, le l'encodage des caractères doit être UTF-8, UTF-16 ou UTF-32. US-ASCII est haut-compatible avec l'encodage UTF-8 (un La chaîne US-ASCII est aussi UTF-8 de chaîne, voir [RFC 3629]), et UTF-8 est par conséquent approprié, si la compatibilité chez nous-ASCII est désiré." Dans pratique, compatibilité avec US-ASCII est si utile, c'est presque un exigence. Le W3C explique sagement, "Dans d'autres situations, comme pour les Les IPA, UTF-16 ou UTF-32 peuvent être plus approprié. Les raisons possibles pour le choix de l'une de ces l'efficacité du traitement interne et l'interopérabilité avec autre processus."
comme tout le monde l'a dit, UTF-8, UTF-16 et UTF-32 peuvent tous encoder tous les points de code Unicode. Cependant , la variante UCS-2 (parfois appelée par erreur UCS-16) ne peut pas , et c'est celle que vous trouvez par exemple dans Windows XP/Vista .
Voir Wikipedia pour plus d'informations.
Edit: je suis dans l'erreur à propos de Windows, NT a été le seul à supporter UCS-2. Cependant, beaucoup D'applications Windows supposeront un seul mot par point de code comme dans UCS-2, donc vous êtes susceptible de trouver des bogues. Voir un autre article de Wikipedia . (Merci JasonTrue)