wake-up-neo.com

UTF-8, UTF-16 und UTF-32

Was sind die Unterschiede zwischen UTF-8, UTF-16 und UTF-32?

Ich verstehe, dass sie alle Unicode speichern und dass jeder eine andere Anzahl von Bytes verwendet, um ein Zeichen darzustellen. Gibt es einen Vorteil, wenn man einen über den anderen wählt?

450
Joe

UTF-8 hat den Vorteil, dass ASCII Zeichen die Mehrheit der Zeichen in einem Textblock darstellen, da UTF-8 alle Zeichen in 8 Bits (wie ASCII) codiert Das hat den Vorteil, dass eine UTF-8-Datei, die nur ASCII Zeichen enthält, dieselbe Codierung wie eine ASCII Datei hat.

UTF-16 ist besser, wenn ASCII ist nicht vorherrschend, da es hauptsächlich 2 Bytes pro Zeichen verwendet. UTF-8 beginnt, 3 oder mehr Bytes für Zeichen höherer Ordnung zu verwenden, wenn UTF-16 bleibt für die meisten Zeichen bei nur 2 Byte.

UTF-32 deckt alle möglichen Zeichen in 4 Bytes ab. Das macht es ziemlich aufgebläht. Ich kann mir keinen Vorteil vorstellen, wenn ich es benutze.

339
AnthonyWJones

Zusamenfassend:

  • UTF-8: Codierung mit variabler Breite, abwärtskompatibel mit ASCII. ASCII Zeichen (U + 0000 bis U + 007F) belegen 1 Byte, Codepunkte U + 0080 bis U + 07FF belegen 2 Byte, Codepunkte U + 0800 bis U + FFFF belegen 3 Byte, Die Codepunkte U + 10000 bis U + 10FFFF benötigen 4 Bytes. Gut für englischen Text, nicht so gut für asiatischen Text.
  • UTF-16: Codierung mit variabler Breite. Codepunkte U + 0000 bis U + FFFF benötigen 2 Byte, Codepunkte U + 10000 bis U + 10FFFF 4 Byte. Schlecht für englischen Text, gut für asiatischen Text.
  • UTF-32: Codierung mit fester Breite. Alle Codepunkte benötigen vier Bytes. Ein riesiges Gedächtnisschwein, aber schnell zu bearbeiten. Selten genutzt.

Lange: siehe Wikipedia: TF-8 , TF-16 und TF-32 .

299
Adam Rosenfield
  • UTF-8 ist variabel 1 bis 4 Bytes.

  • UTF-16 ist variabel 2 oder 4 Bytes.

  • UTF-32 ist fest 4 Bytes.

108
Quassnoi

Unicode definiert einen einzelnen großen Zeichensatz, indem jedem grafischen Symbol ein eindeutiger ganzzahliger Wert zugewiesen wird (dies ist eine wesentliche Vereinfachung und nicht wahr, aber für die Zwecke dieser Frage nahe genug). UTF-8/16/32 sind einfach verschiedene Möglichkeiten, dies zu codieren.

Kurz gesagt, UTF-32 verwendet 32-Bit-Werte für jedes Zeichen. Dadurch können sie für jedes Zeichen einen Code mit fester Breite verwenden.

UTF-16 verwendet standardmäßig 16-Bit, dies ergibt jedoch nur 65.000 mögliche Zeichen, was für den vollständigen Unicode-Satz bei weitem nicht ausreicht. Einige Zeichen verwenden daher Paare von 16-Bit-Werten.

Und UTF-8 verwendet standardmäßig 8-Bit-Werte. Dies bedeutet, dass die 127 ersten Werte Einzelbyte-Zeichen mit fester Breite sind (das höchstwertige Bit wird verwendet, um anzuzeigen, dass dies der Beginn einer Mehrbyte-Sequenz ist, sodass 7 übrig bleibt Bits für den tatsächlichen Zeichenwert). Alle anderen Zeichen werden als Sequenzen von bis zu 4 Bytes codiert (sofern der Speicher belegt ist).

Und das bringt uns zu den Vorteilen. Da jedes ASCII-Zeichen direkt mit UTF-8 kompatibel ist, ist UTF-8 für die Aktualisierung älterer Apps eine häufige und naheliegende Wahl. In fast allen Fällen wird auch der geringste Speicher belegt. Auf der anderen Seite können Sie keine Garantie für die Breite eines Zeichens geben. Es kann 1, 2, 3 oder 4 Zeichen breit sein, was die Manipulation von Zeichenfolgen erschwert.

UTF-32 ist das Gegenteil, es belegt den meisten Speicher (jedes Zeichen hat eine feste Breite von 4 Bytes), aber auf der anderen Seite wissen dass jedes Zeichen genau diese Länge hat, so dass die Manipulation von Zeichenfolgen zu weit geht einfacher. Sie können die Anzahl der Zeichen in einer Zeichenfolge einfach aus der Länge der Zeichenfolge in Byte berechnen. Mit UTF-8 ist das nicht möglich.

UTF-16 ist ein Kompromiss. Hiermit können die meisten Zeichen in einen 16-Bit-Wert mit fester Breite eingefügt werden. Solange Sie keine chinesischen Symbole, Noten oder andere Zeichen haben, können Sie davon ausgehen, dass jedes Zeichen 16 Bit breit ist. Es benötigt weniger Speicher als UTF-32. Aber es ist in gewisser Weise "das Schlimmste von beiden Welten". Es belegt fast immer mehr Speicher als UTF-8 und vermeidet immer noch nicht das Problem, das UTF-8 (Zeichen variabler Länge) plagt.

Schließlich ist es oft hilfreich, einfach das zu wählen, was die Plattform unterstützt. Windows verwendet intern UTF-16, daher ist dies unter Windows die naheliegende Wahl.

Linux variiert ein bisschen, aber im Allgemeinen verwenden sie UTF-8 für alles, was Unicode-kompatibel ist.

Also kurze Antwort: Alle drei Kodierungen können denselben Zeichensatz kodieren, aber sie repräsentieren jedes Zeichen als unterschiedliche Byte-Sequenzen.

74
jalf

Unicode ist ein Standard und ungefähr UTF-x kann man sich als technische Umsetzung für einige praktische Zwecke:

  • TF-8 - "größenoptimiert": am besten für lateinische Zeichen (oder ASCII) geeignet, es dauert nur 1 Byte pro Zeichen, aber die Größe wächst entsprechend der Symbolvielfalt ( und im schlimmsten Fall kann es bis zu 6 Bytes pro Zeichen werden.)
  • TF-16 - "balance": Es werden mindestens 2 Bytes pro Zeichen benötigt, was ausreicht, um die Zeichenhandhabung zu vereinfachen, wenn die Mainstream-Sprachen eine feste Größe haben ( Die Größe ist jedoch noch variabel und kann bis zu 4 Byte pro Zeichen betragen.)
  • TF-32 - "performance": Ermöglicht die Verwendung einfacher Algorithmen als Ergebnis von Zeichen mit fester Größe (4 Byte), jedoch mit Speichernachteil
41
rook

Ich habe versucht, in meinem Blogpost eine einfache Erklärung zu geben.

UTF-32

erfordert 32 Bits (4 Bytes) zum Codieren eines Zeichens. Um beispielsweise den Code-Punkt mit dem Zeichen "A" nach diesem Schema darzustellen, müssen Sie 65 in 32-Bit-Binärzahl schreiben:

00000000 00000000 00000000 01000001 (Big Endian)

Wenn Sie genauer hinsehen, werden Sie feststellen, dass die am weitesten rechts stehenden sieben Bits tatsächlich dieselben Bits sind, wenn Sie das Schema ASCII= verwenden. Da UTF-32 jedoch Schema mit fester Breite , wir müssen drei zusätzliche Bytes anhängen, dh wenn wir zwei Dateien haben, die nur das "A" -Zeichen enthalten, ist eine ASCII-codiert und die andere ist UTF- 32 codiert, ihre Größe wird 1 Byte und 4 Bytes entsprechend sein.

UTF-16

Viele Leute denken, dass UTF-16 eine feste Breite von 16 Bit hat, da UTF-32 eine feste Breite von 32 Bit verwendet, um einen Codepunkt darzustellen. FALSCH!

In UTF-16 kann der Codepunkt entweder in 16 Bits dargestellt werden, OR 32 Bits. Dieses Schema ist also ein Codierungssystem mit variabler Länge. Was ist der Vorteil gegenüber UTF-32? Zumindest für ASCII , die Dateigröße wird nicht das 4-fache der Originalgröße betragen (aber immer noch das 2-fache), daher sind wir immer noch nicht ASCII abwärtskompatibel.

Da 7-Bit ausreichen, um das "A" -Zeichen darzustellen, können wir jetzt wie beim UTF-32 2 Bytes anstelle von 4 Bytes verwenden. Es wird so aussehen:

00000000 01000001

UTF-8

Sie haben richtig geraten. In UTF-8 kann der Codepunkt entweder mit 32, 16, 24 oder 8 Bits dargestellt werden, und als UTF-16-System ist dies auch ein Codiersystem mit variabler Länge.

Schließlich können wir "A" so darstellen, wie wir es darstellen, indem wir ASCII Codierungssystem:

01001101

Ein kleines Beispiel, in dem UTF-16 tatsächlich besser ist als UTF-8:

Betrachten Sie den chinesischen Buchstaben "語" - seine UTF-8-Codierung lautet:

11101000 10101010 10011110

Während die UTF-16-Codierung kürzer ist:

10001010 10011110

Um die Darstellung zu verstehen und wie sie interpretiert wird, besuchen Sie den Originalbeitrag.

22
Maroun

UTF-8

  • hat kein Konzept der Bytereihenfolge
  • verwendet zwischen 1 und 4 Bytes pro Zeichen
  • ASCII ist eine kompatible Teilmenge der Codierung
  • vollständig selbstsynchronisierend, z.B. Ein von einer beliebigen Stelle in einem Stream abgelegtes Byte kann höchstens ein einzelnes Zeichen beschädigen
  • fast alle europäischen Sprachen sind in zwei Bytes oder weniger pro Zeichen kodiert

UTF-16

  • muss mit bekannter Bytereihenfolge analysiert werden oder eine Bytereihenfolge-Markierung (BOM) lesen
  • verwendet entweder 2 oder 4 Bytes pro Zeichen

UTF-32

  • jedes Zeichen besteht aus 4 Bytes
  • muss mit bekannter Bytereihenfolge analysiert werden oder eine Bytereihenfolge-Markierung (BOM) lesen

UTF-8 ist am platzsparendsten, es sei denn, die meisten Zeichen stammen aus dem CJK-Zeichenbereich (Chinesisch, Japanisch und Koreanisch).

UTF-32 eignet sich am besten für den wahlfreien Zugriff durch Zeichenversatz in ein Byte-Array.

19
Jeff Adamson

In UTF-32 werden alle Zeichen mit 32 Bit codiert. Der Vorteil ist, dass Sie die Länge der Zeichenfolge leicht berechnen können. Der Nachteil ist, dass Sie für jedes ASCII Zeichen drei zusätzliche Bytes verschwenden.

In UTF-8-Zeichen mit variabler Länge werden ASCII Zeichen werden in einem Byte (acht Bits) codiert, die meisten westlichen Sonderzeichen werden entweder in zwei Bytes oder drei Bytes codiert (zum Beispiel beträgt € drei Bytes) ) und exotischere Zeichen können bis zu vier Bytes lang sein. Klarer Nachteil ist, dass Sie die Länge der Zeichenfolge nicht von vornherein berechnen können. Der Code von lateinischem (englischem) Alphabet erfordert jedoch viel weniger Bytes als UTF-32.

UTF-16 ist auch eine variable Länge. Zeichen werden entweder in zwei oder vier Bytes codiert. Ich verstehe den Punkt wirklich nicht. Es hat den Nachteil einer variablen Länge, hat aber nicht den Vorteil, so viel Platz zu sparen wie UTF-8.

Von diesen drei ist UTF-8 eindeutig am weitesten verbreitet.

13
vartec

Ich habe einige Tests durchgeführt, um die Datenbankleistung zwischen UTF-8 und UTF-16 in MySQL zu vergleichen.

Update-Geschwindigkeiten

UTF-8

Enter image description here

UTF-16

Enter image description here

Geschwindigkeiten einfügen

Enter image description here

Enter image description here

Geschwindigkeiten löschen

Enter image description here

Enter image description here

13
Farid Movsumov

Abhängig von Ihrer Entwicklungsumgebung haben Sie möglicherweise nicht einmal die Wahl, welche Codierung Ihr String-Datentyp intern verwenden soll.

Aber zum Speichern und Austauschen von Daten würde ich immer UTF-8 verwenden, wenn Sie die Wahl haben. Wenn Sie hauptsächlich ASCII Daten haben, erhalten Sie die geringste zu übertragende Datenmenge, während Sie dennoch in der Lage sind, alles zu codieren. Optimierungen für die geringste Anzahl von E/A sind der Weg zu modernen Maschinen .

6
mghie

Wie bereits erwähnt, liegt der Unterschied hauptsächlich in der Größe der zugrunde liegenden Variablen, die jeweils größer werden, um mehr Zeichen darstellen zu können.

Da Schriften, Codierungen und andere Dinge (unnötigerweise?) Sehr kompliziert sind, ist ein großer Link erforderlich, um die Details zu ergänzen:

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

Erwarten Sie nicht, alles zu verstehen, aber wenn Sie später keine Probleme haben möchten, lohnt es sich, so früh wie möglich so viel wie möglich zu lernen (oder nur jemanden zu beauftragen, dies für Sie zu klären).

Paul.

2
Paul W Homer

Kurz gesagt, der einzige Grund, UTF-16 oder UTF-32 zu verwenden, ist die Unterstützung von nicht-englischen bzw. alten Skripten.

Ich habe mich gefragt, warum sich jemand für eine Nicht-UTF-8-Codierung entschieden hat, wenn sie für Web-/Programmierzwecke offensichtlich effizienter ist.

Ein weit verbreitetes Missverständnis - die angehängte Nummer ist KEIN Hinweis auf ihre Leistungsfähigkeit. Sie alle unterstützen den vollständigen Unicode, nur dass UTF-8 ASCII mit einem einzelnen Byte verarbeiten kann, sodass die CPU und das Internet effizienter bzw. weniger korrumpierbar sind.

Einige gute Lektüre: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html und http://utf8everywhere.org =

0
killjoy