wake-up-neo.com

Unterschied zwischen UTF-8 und UTF-16?

Unterschied zwischen UTF-8 und UTF-16? Warum brauchen wir diese?

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

Ich glaube, es gibt viele gute Artikel darüber im Internet, aber hier ist eine kurze Zusammenfassung.

Sowohl UTF-8 als auch UTF-16 sind Kodierungen mit variabler Länge. In UTF-8 kann ein Zeichen jedoch mindestens 8 Bit belegen, während in UTF-16 die Zeichenlänge mit 16 Bit beginnt.

Haupt-UTF-8-Profis:

  • Basic ASCII Zeichen wie Ziffern, lateinische Zeichen ohne Akzente usw. belegen ein Byte, das mit der US-ASCII-Darstellung identisch ist. Auf diese Weise werden alle US-ASCII-Zeichenfolgen zu gültigen UTF-8-Zeichen in vielen Fällen eine anständige Abwärtskompatibilität.
  • Keine Null-Bytes, wodurch nullterminierte Zeichenfolgen verwendet werden können. Dies führt auch zu einer großen Abwärtskompatibilität.
  • UTF-8 ist unabhängig von der Bytereihenfolge, sodass Sie sich nicht um das Big-Endian-/Little-Endian-Problem kümmern müssen.

Haupt-UTF-8-Nachteile:

  • Viele gebräuchliche Zeichen haben unterschiedliche Längen, was die Indizierung nach Codepunkt verlangsamt und die Codepunktzahl fürchterlich berechnet.
  • Auch wenn die Bytereihenfolge keine Rolle spielt, enthält UTF-8 manchmal immer noch eine Stückliste (Bytereihenfolge), die darauf hinweist, dass der Text in UTF-8 codiert ist, und die Kompatibilität mit ASCII) bricht Software, auch wenn der Text nur ASCII Zeichen enthält. Microsoft-Software (wie Notepad) fügt UTF-8 besonders gerne Stücklisten hinzu.

Haupt-UTF-16-Profis:

  • BMP-Zeichen (Basic Multilingual Plane), einschließlich lateinische, kyrillische und die meisten chinesischen Zeichen (die VR China hat die Unterstützung einiger Codepunkte außerhalb von BMP obligatorisch), die meisten japanischen Zeichen können mit 2 Byte dargestellt werden. Dies beschleunigt die Indizierung und Berechnung der Codepunktzahl, falls der Text keine zusätzlichen Zeichen enthält.
  • Auch wenn der Text zusätzliche Zeichen enthält, werden sie immer noch durch 16-Bit-Wertepaare dargestellt. Dies bedeutet, dass die Gesamtlänge immer noch durch zwei teilbar ist und die Verwendung von 16-Bit char als Grundkomponente der zulässt Zeichenfolge.

Haupt-UTF-16-Nachteile:

  • Viele Null-Bytes in US-ASCII-Zeichenfolgen, dh keine nullterminierten Zeichenfolgen und viel verschwendeter Speicher.
  • Die Verwendung als Codierung mit fester Länge „funktioniert meistens“ in vielen gängigen Szenarien (insbesondere in den USA/der EU/Ländern mit kyrillischen Buchstaben/Israel/arabischen Ländern/Iran und vielen anderen Ländern), was häufig zu fehlerhafter Unterstützung führt, wenn dies nicht der Fall ist. Dies bedeutet, dass die Programmierer Ersatzpaare kennen und in Fällen, in denen es darauf ankommt, richtig damit umgehen müssen!
  • Die Länge ist variabel, daher ist das Zählen oder Indizieren von Codepunkten kostspielig, wenn auch weniger als UTF-8.

Im Allgemeinen ist UTF-16 für die Darstellung im Speicher besser, da BE/LE dort irrelevant ist (verwenden Sie einfach die native Reihenfolge) und die Indizierung schneller ist (vergessen Sie nur nicht, die Ersatzpaare richtig zu behandeln). UTF-8 hingegen eignet sich hervorragend für Textdateien und Netzwerkprotokolle, da es kein BE/LE-Problem gibt und eine Nullterminierung häufig nützlich ist sowie ASCII-Kompatibilität bietet.

278
Sergei Tachenov

Es sind einfach verschiedene Schemata zur Darstellung von Unicode-Zeichen.

Beide sind variabel lang - UTF-16 verwendet 2 Byte für alle Zeichen in der mehrsprachigen Basisebene (BMP), die die meisten häufig verwendeten Zeichen enthält.

UTF-8 verwendet zwischen 1 und 3 Byte für Zeichen im BMP, bis zu 4 Byte für Zeichen im aktuellen Unicode-Bereich von U + 0000 bis U + 1FFFFF und ist erweiterbar auf U + 7FFFFFFF, falls dies jemals erforderlich wird ... Insbesondere werden jedoch alle ASCII - Zeichen in jeweils einem Byte dargestellt.

Für die Zwecke eines Nachrichten-Digests spielt es keine Rolle, welche davon Sie auswählen, solange jeder, der versucht, den Digest neu zu erstellen, dieselbe Option verwendet.

Weitere Informationen zu UTF-8 und Unicode finden Sie unter diese Seite .

(Beachten Sie, dass alle Java Zeichen UTF-16-Codepunkte innerhalb des BMP sind. Um Zeichen über U + FFFF darzustellen, müssen Sie in Java Ersatzpaare verwenden.)

18
Jon Skeet

Dies hat nichts mit UTF-8/16 zu tun (im Allgemeinen, obwohl es in UTF16 konvertiert wird und der BE/LE-Teil mit einer einzelnen Zeile festgelegt werden kann). Im Folgenden wird jedoch die schnellste Methode zum Konvertieren von String in Byte [] beschrieben. Zum Beispiel: gut genau für den angegebenen Fall (Hash-Code). String.getBytes (enc) ist relativ langsam.

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

Sicherheit: Verwenden Sie nur UTF-8

Unterschied zwischen UTF-8 und UTF-16? Warum brauchen wir diese?

In Implementierungen von TF-16 sind mindestens einige Sicherheitslücken aufgetreten. Siehe Wikipedia für Details .

WHATWG und W3C haben jetzt deklariert dass nur TF-8 ist im Web verwendet werden.

Die hier beschriebenen [Sicherheit] -Probleme verschwinden, wenn ausschließlich UTF-8 verwendet wird. Dies ist einer der vielen Gründe, aus denen jetzt die obligatorische Kodierung für alle Dinge erfolgt.

Andere Gruppen sagen dasselbe.

Während UTF-16 möglicherweise weiterhin intern von einigen Systemen wie Java und Windows verwendet wird, kann es sein, dass Sie in der Vergangenheit nur wenig UTF-16 für Datendateien, den Datenaustausch usw. verwendet haben solche, wird wahrscheinlich ganz verblassen.

0
Basil Bourque