web-dev-qa-db-fra.com

Différence entre UTF-8 et UTF-16?

Différence entre UTF-8 et UTF-16? Pourquoi avons-nous besoin de cela?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
132
theJava

Je crois qu’il existe de nombreux articles intéressants à ce sujet sur le Web, mais voici un bref résumé.

UTF-8 et UTF-16 sont tous deux des codages à longueur variable. Cependant, dans UTF-8, un caractère peut occuper un minimum de 8 bits, tandis que dans UTF-16, la longueur de caractère commence par 16 bits.

Principaux avantages de l'UTF-8:

  • Les caractères de base ASCII tels que les chiffres, les caractères latins sans accent, etc. occupent un octet, ce qui est identique à la représentation US-ASCII. De cette façon, toutes les chaînes US-ASCII deviennent UTF-8, ce qui offre une compatibilité ascendante décente dans de nombreux cas.
  • Aucun octet nul, ce qui permet d'utiliser des chaînes terminées par un caractère nul, cela introduit également une compatibilité ascendante importante.
  • UTF-8 est indépendant de l'ordre des octets, vous n'avez donc pas à vous soucier du problème Big Endian/Little Endian.

Principaux inconvénients du UTF-8:

  • De nombreux caractères communs ont des longueurs différentes, ce qui ralentit l'indexation par point de code et le calcul du nombre de points de code.
  • Même si l'ordre des octets n'a pas d'importance, UTF-8 a parfois toujours BOM (marque d'ordre d'octet) qui sert à notifier que le texte est codé en UTF-8, et rompt également la compatibilité avec le logiciel ASCII même si le texte ne contient que ASCII caractères. Les logiciels Microsoft (comme le Bloc-notes) aiment particulièrement ajouter une nomenclature à UTF-8.

Principaux avantages de l'UTF-16:

  • Caractères BMP (plan multilingue de base), notamment latin, cyrillique, la plupart des chinois (la PRC a pris en charge certains points de codage en dehors de BMP obligatoire), la plupart des japonais pouvant être représentés avec 2 octets. Cela accélère l'indexation et le calcul du nombre de points de code au cas où le texte ne contient pas de caractères .
  • Même si le texte a des caractères supplémentaires, ils sont toujours représentés par des paires de valeurs de 16 bits, ce qui signifie que la longueur totale est toujours divisible par deux et permet d’utiliser char de 16 bits comme composant primitif du fichier. chaîne.

Principaux inconvénients du UTF-16:

  • Beaucoup d'octets nuls dans les chaînes US-ASCII, ce qui signifie pas de chaînes terminées par zéro et beaucoup de mémoire gaspillée.
  • Son utilisation en tant que codage de longueur fixe “fonctionne généralement” dans de nombreux scénarios courants (notamment aux États-Unis/dans l’Union européenne/dans les pays alphabets cyrilliques/Israël/dans les pays arabes/en Iran et dans d’autres), ce qui aboutit souvent à une prise en charge incomplète. Cela signifie que les programmeurs doivent être conscients des paires de substitution et les manipuler correctement dans les cas où cela compte!
  • C'est une longueur variable, donc compter ou coder des points de code est coûteux, mais moins que UTF-8.

En général, UTF-16 est généralement préférable pour la représentation en mémoire car BE/LE n'y est pas pertinent (il suffit d'utiliser l'ordre natif) et l'indexation est plus rapide (n'oubliez pas de gérer correctement les paires de substitution). UTF-8, en revanche, est extrêmement bon pour les fichiers texte et les protocoles réseau car il n’ya pas de problème BE/LE et la terminaison nulle est souvent utile, ainsi que la compatibilité ASCII.

278
Sergei Tachenov

Ce sont simplement des schémas différents pour représenter les caractères Unicode.

Les deux sont de longueur variable - UTF-16 utilise 2 octets pour tous les caractères du plan multilingue de base (BMP), qui contient la plupart des caractères couramment utilisés.

UTF-8 utilise entre 1 et 3 octets pour les caractères dans le BMP, jusqu'à 4 pour les caractères dans la plage Unicode actuelle de U + 0000 à U + 1FFFFF, et est extensible jusqu'à U + 7FFFFFFF si cela devient nécessaire ... mais notamment tous les caractères ASCII) sont représentés dans un seul octet chacun.

Pour les besoins du résumé de message, le choix de votre choix importe peu, tant que tous ceux qui tentent de recréer le résumé utilisent la même option.

Voir cette page pour plus d'informations sur UTF-8 et Unicode.

(Notez que tous les caractères Java sont des points de code UTF-16 dans le BMP; pour représenter des caractères supérieurs à U + FFFF, vous devez utiliser des paires de substitution en Java.)

18
Jon Skeet

Ceci n’est pas lié à UTF-8/16 (en général, bien qu’il convertisse en UTF16 et que la partie BE/LE puisse être définie avec une seule ligne), le calcul ci-dessous est le moyen le plus rapide de convertir String en octet []. Par exemple: bon exactement pour le cas fourni (code de hachage). String.getBytes (enc) est relativement lent.

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }
4
bestsss

Sécurité: Utilisez uniquement UTF-8

Différence entre UTF-8 et UTF-16? Pourquoi avons-nous besoin de cela?

Il y a eu au moins quelques vulnérabilités de sécurité dans les implémentations de TF-16 . Voir Wikipedia pour plus de détails .

WHATWG et W3C ont maintenant déclaré que seul TF-8 est être utilisé sur le Web.

Les problèmes de [sécurité] décrits ici disparaissent lorsque vous utilisez exclusivement UTF-8, ce qui est l'une des nombreuses raisons pour lesquelles le codage est désormais obligatoire.

D'autres groupes disent la même chose.

Ainsi, même si UTF-16 peut continuer à être utilisé en interne par certains systèmes tels que Java et Windows, le peu d’utilité d’UTF-16 que vous avez pu observer auparavant pour les fichiers de données, l’échange de données et tels, vont probablement disparaître complètement.

0
Basil Bourque