web-dev-qa-db-fra.com

Quel est l'intérêt de l'UTF-16?

Je n'ai jamais compris l'intérêt de l'encodage UTF-16. Si vous devez pouvoir traiter les chaînes comme un accès aléatoire (c'est-à-dire qu'un point de code est le même qu'une unité de code), vous avez besoin d'UTF-32, car UTF-16 est toujours de longueur variable. Si vous n'en avez pas besoin, alors l'UTF-16 semble être un énorme gaspillage d'espace par rapport à l'UTF-8. Quels sont les avantages de UTF-16 par rapport à UTF-8 et UTF-32 et pourquoi Windows et Java l'utilisent-ils comme encodage natif?

67
dsimcha

Lorsque Windows NT a été conçu, UTF-16 n'existait pas (NT 3.51 est né en 1993, tandis que UTF-16 est né en 1996 avec la norme Unicode 2.0); il y avait à la place UCS-2, qui, à ce moment-là, était suffisant pour contenir tous les caractères disponibles dans Unicode, donc l'équivalence 1 point de code = 1 unité de code était réellement vraie - aucune logique de longueur variable n'était nécessaire pour les chaînes.

Ils sont passés à UTF-16 plus tard, pour prendre en charge l'ensemble du jeu de caractères Unicode; cependant, ils ne pouvaient pas passer à UTF-8 ou à UTF-32, car cela aurait brisé la compatibilité binaire dans l'interface API (entre autres).

Quant à Java, je ne suis pas vraiment sûr; depuis sa sortie en ~ 1995, je soupçonne que l'UTF-16 était déjà dans l'air (même s'il n'était pas encore standardisé), mais je pense que la compatibilité avec les systèmes d'exploitation basés sur NT peut avoir joué un certain rôle dans leur choix (continu Les conversions UTF-8 <-> UTF-16 pour chaque appel aux API Windows peuvent entraîner un certain ralentissement).


Modifier

Wikipedia explique que même pour Java cela a fonctionné de la même manière: il supportait à l'origine UCS-2, mais est passé à UTF-16 dans J2SE 5.0.

Donc, en général, lorsque vous voyez UTF-16 utilisé dans certaines API/Framework, c'est parce qu'il a commencé comme UCS-2 (pour éviter les complications dans les algorithmes de gestion des chaînes), mais il est passé à UTF-16 pour prendre en charge les points de code en dehors de la BMP, conservant toujours la même taille d'unité de code.

47
Matteo Italia

Aucune des réponses indiquant un avantage de l'UTF-16 par rapport à l'UTF-8 n'a de sens, à l'exception de la réponse de compatibilité descendante.

Eh bien, il y a deux mises en garde à mon commentaire.

Erik déclare: "UTF-16 couvre l'ensemble BMP avec des unités simples - Donc, à moins que vous n'ayez besoin de caractères plus rares en dehors du BMP, UTF-16 est en fait de 2 octets par caractère."

Avertissement 1)

Si vous pouvez être certain que votre application n'aura JAMAIS besoin de caractère en dehors du BMP, et que tout code de bibliothèque que vous écrivez pour l'utiliser avec elle ne sera JAMAIS utilisé avec une application qui aura jamais besoin d'un caractère en dehors du BMP, alors vous pourriez utiliser UTF-16 et écrire du code qui fait l'hypothèse implicite que chaque caractère aura exactement deux octets de longueur.

Cela semble extrêmement dangereux (en fait, stupide).

Si votre code suppose que tous les caractères UTF-16 ont une longueur de deux octets et que votre programme interagit avec une application ou une bibliothèque où il n'y a qu'un seul caractère en dehors du BMP, alors votre code se cassera. Le code qui examine ou manipule UTF-16 doit être écrit pour gérer la casse d'un caractère UTF-16 nécessitant plus de 2 octets; par conséquent, je "rejette" cette mise en garde.

UTF-16 n'est pas plus simple à coder que UTF-8 (le code pour les deux doit gérer les caractères de longueur variable).

Mise en garde 2)

L'UTF-16 POURRAIT être plus efficace en termes de calcul, dans certaines circonstances, s'il est correctement écrit.

Comme ceci: Supposons que certaines chaînes longues soient rarement modifiées, mais souvent examinées (ou mieux, jamais modifiées une fois construites - c'est-à-dire, un générateur de chaînes créant des chaînes non modifiables). Un indicateur pourrait être défini pour chaque chaîne, indiquant si la chaîne ne contient que des caractères de "longueur fixe" (c'est-à-dire, ne contient aucun caractère dont la longueur n'est pas exactement de deux octets). Les chaînes pour lesquelles l'indicateur est vrai peuvent être examinées avec un code optimisé qui suppose des caractères de longueur fixe (2 octets).

Que diriez-vous de l'espace-efficacité?

UTF-16 est évidemment plus efficace pour les caractères A) pour lesquels UTF-16 nécessite moins d'octets pour coder que UTF-8.

UTF-8 est évidemment plus efficace pour les caractères B) pour lesquels UTF-8 nécessite moins d'octets pour coder que UTF-16.

Sauf pour le texte très "spécialisé", il est probable que le nombre (B) dépasse de loin le nombre (A).

19
user3162129

UTF-16 couvre la totalité BMP avec des unités simples - Donc, à moins que vous n'ayez besoin des caractères les plus rares en dehors du BMP, UTF-16 est en fait de 2 octets par personnage. UTF-32 prend plus d'espace, UTF-8 nécessite un support de longueur variable.

3
Erik

UTF16 est généralement utilisé comme un mappage direct avec des jeux de caractères multi-octets, c'est-à-dire uniquement les caractères assignés d'origine 0-0xFFFF.

Cela vous donne le meilleur des deux mondes, vous avez une taille de caractère fixe mais vous pouvez toujours imprimer tous les caractères que n'importe qui est susceptible d'utiliser (à l'exception des scripts religieux Klingon orthodoxes)

1
Martin Beckett

UTF-16 permet à tous les plans multilingues de base (BMP) d'être représentés comme des unités de code unique. Les points de code Unicode au-delà de U + FFFF sont représentés par des paires de substitution.

La chose intéressante est que Java et Windows (et d'autres systèmes qui utilisent UTF-16) fonctionnent tous au niveau de l'unité de code, pas au niveau du point de code Unicode. Ainsi, la chaîne composée du caractère unique U + 1D122 (SYMBOLE MUSICAL F CLEF) est encodé en Java comme "\ ud824\udd22" et "\ud824\udd22".length() == 2 (pas 1). C'est donc une sorte de hack, mais il s'avère que les caractères ne sont pas de longueur variable.

L'avantage d'UTF-16 sur UTF-8 est que l'on abandonnerait trop si le même hack était utilisé avec UTF-8.

1
Ted Hopp