Was sind die Unterschiede zwischen UTF-8, UTF-16 und UTF-32?
Ich verstehe, dass sie alle Unicode speichern und dass jedes eine andere Anzahl von Bytes verwendet, um ein Zeichen darzustellen. Gibt es einen Vorteil, wenn man sich für einen entscheidet?
Antworten:
UTF-8 hat den Vorteil, dass ASCII-Zeichen die Mehrheit der Zeichen in einem Textblock darstellen, da UTF-8 diese in 8 Bit codiert (wie ASCII). Es ist auch insofern vorteilhaft, als eine UTF-8-Datei, die nur ASCII-Zeichen enthält, dieselbe Codierung wie eine ASCII-Datei hat.
UTF-16 ist besser, wenn ASCII nicht vorherrscht, da hauptsächlich 2 Bytes pro Zeichen verwendet werden. UTF-8 beginnt, 3 oder mehr Bytes für die Zeichen höherer Ordnung zu verwenden, wobei UTF-16 für die meisten Zeichen bei nur 2 Bytes bleibt.
UTF-32 deckt alle möglichen Zeichen in 4 Bytes ab. Das macht es ziemlich aufgebläht. Ich kann mir keinen Vorteil vorstellen, es zu benutzen.
quelle
Zusamenfassend:
Lang: siehe Wikipedia: UTF-8 , UTF-16 und UTF-32 .
quelle
wchar_t
standardmäßig 4 Byte verwendet. gcc hat eine Option-fshort-wchar
, die die Größe auf 2 Bytes reduziert, aber die Binärkompatibilität mit std libs unterbricht.UTF-8 ist eine Variable von 1 bis 4 Bytes.
UTF-16 ist eine Variable von 2 oder 4 Bytes.
UTF-32 ist fest auf 4 Bytes eingestellt.
Hinweis: UTF-8 kann mit der neuesten Konvention 1 bis 6 Byte benötigen: https://lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html
quelle
Unicode definiert einen einzelnen großen Zeichensatz, der jedem grafischen Symbol einen eindeutigen ganzzahligen Wert zuweist (dies ist eine wesentliche Vereinfachung und nicht wirklich wahr, aber für die Zwecke dieser Frage nah 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, aber das gibt Ihnen 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, was bedeutet, dass die ersten 127 Werte Einzelbyte-Zeichen mit fester Breite sind (das höchstwertige Bit wird verwendet, um anzuzeigen, dass dies der Beginn einer Mehrbyte-Sequenz ist, wobei 7 übrig bleibt Bits für den tatsächlichen Zeichenwert). Alle anderen Zeichen werden als Sequenzen von bis zu 4 Bytes codiert (sofern Speicher vorhanden ist).
Und das führt uns zu den Vorteilen. Jedes ASCII-Zeichen ist direkt mit UTF-8 kompatibel. Für die Aktualisierung älterer Apps ist UTF-8 daher eine häufige und offensichtliche Wahl. In fast allen Fällen wird auch der geringste Speicher verwendet. 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 schwierig macht.
UTF-32 ist das Gegenteil, es verwendet den meisten Speicher (jedes Zeichen hat eine feste Breite von 4 Byte), aber andererseits wissen Sie , dass jedes Zeichen genau diese Länge hat, sodass die Manipulation von Zeichenfolgen viel einfacher wird. Sie können die Anzahl der Zeichen in einer Zeichenfolge einfach aus der Länge der Zeichenfolge in Byte berechnen. Mit UTF-8 geht das nicht.
UTF-16 ist ein Kompromiss. Damit können die meisten Zeichen in einen 16-Bit-Wert mit fester Breite passen. Solange Sie keine chinesischen Symbole, Noten oder andere 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 aus beiden Welten". Es verwendet 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, nur das zu wählen, was die Plattform unterstützt. Windows verwendet UTF-16 intern, daher ist dies unter Windows die naheliegende Wahl.
Linux variiert ein wenig, aber sie verwenden UTF-8 im Allgemeinen für alles, was Unicode-kompatibel ist.
So kurze Antwort: Alle drei Codierungen können denselben Zeichensatz codieren, aber sie repräsentieren jedes Zeichen als unterschiedliche Byte-Sequenzen.
quelle
Unicode ist ein Standard und über UTF-x können Sie als technische Implementierung für einige praktische Zwecke denken:
quelle
Ich habe versucht, in meinem Blogpost eine einfache Erklärung zu geben .
UTF-32
benötigt 32 Bit (4 Bytes), um ein beliebiges Zeichen zu codieren . Um beispielsweise den Codepunkt "A" mit diesem Schema darzustellen, müssen Sie 65 in eine 32-Bit-Binärzahl schreiben:
Wenn Sie genauer hinschauen, werden Sie feststellen, dass die am weitesten rechts liegenden sieben Bits bei Verwendung des ASCII-Schemas tatsächlich dieselben Bits sind. Da UTF-32 jedoch ein Schema mit fester Breite ist , müssen drei zusätzliche Bytes angehängt werden. Das heißt, wenn wir zwei Dateien haben, die nur das "A" -Zeichen enthalten, eine ASCII-codiert und die andere UTF-32-codiert ist, beträgt ihre Größe entsprechend 1 Byte und 4 Byte.
UTF-16
Viele Leute denken, dass UTF-32 eine feste Breite von 16 Bit verwendet, da UTF-32 eine feste Breite von 32 Bit verwendet, um einen Codepunkt darzustellen. FALSCH!
In UTF-16 kann der Codepunkt entweder in 16 Bit oder in 32 Bit dargestellt werden. Dieses Schema ist also ein Codierungssystem mit variabler Länge. Was ist der Vorteil gegenüber dem UTF-32? Zumindest für ASCII ist die Größe der Dateien nicht viermal so groß wie das Original (aber immer noch zweimal), sodass wir immer noch nicht abwärtskompatibel mit ASCII sind.
Da 7-Bit ausreichen, um das "A" -Zeichen darzustellen, können wir jetzt 2 Bytes anstelle von 4 wie beim UTF-32 verwenden. Es wird so aussehen:
UTF-8
Sie haben richtig geraten. In UTF-8 kann der Codepunkt entweder mit 32, 16, 24 oder 8 Bit dargestellt werden, und als UTF-16-System ist dieses auch ein Codierungssystem mit variabler Länge.
Schließlich können wir "A" genauso darstellen, wie wir es mit dem ASCII-Codierungssystem darstellen:
Ein kleines Beispiel, bei dem UTF-16 tatsächlich besser ist als UTF-8:
Betrachten Sie den chinesischen Buchstaben "語" - seine UTF-8-Codierung lautet:
Während die UTF-16-Codierung kürzer ist:
Um die Darstellung und ihre Interpretation zu verstehen, besuchen Sie den Originalbeitrag.
quelle
UTF-8
UTF-16
UTF-32
UTF-8 wird am platzsparendsten sein, es sei denn, ein Großteil der Zeichen stammt 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.
quelle
0xxxxxxx
in Binärform haben. Alle Zwei-Byte-Zeichen beginnen110xxxxx
mit einem zweiten Byte von10xxxxxx
. Nehmen wir also an, das erste Zeichen eines Zwei-Byte-Zeichens geht verloren. Sobald Sie10xxxxxx
ohne Vorgänger sehen110xxxxxx
, können Sie sicher sein, dass ein Byte verloren gegangen oder beschädigt ist, dieses Zeichen verwerfen (oder es erneut von einem Server oder was auch immer anfordern) und fortfahren, bis Sie wieder ein gültiges erstes Byte sehen .Ich habe einige Tests durchgeführt, um die Datenbankleistung zwischen UTF-8 und UTF-16 in MySQL zu vergleichen.
Geschwindigkeiten aktualisieren
UTF-8
UTF-16
Geschwindigkeiten einfügen
Geschwindigkeiten löschen
quelle
In UTF-32 sind 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 zusätzliche drei Bytes verschwenden.
In UTF-8-Zeichen mit variabler Länge werden ASCII-Zeichen in einem Byte (acht Bit) codiert, die meisten westlichen Sonderzeichen werden entweder in zwei Bytes oder drei Bytes (z. B. € drei Bytes) codiert und es können exotischere Zeichen verwendet werden auf vier Bytes. Ein klarer Nachteil ist, dass Sie die Länge der Zeichenfolge a priori nicht berechnen können. Im Vergleich zu UTF-32 sind jedoch viel weniger Bytes erforderlich, um lateinischen (englischen) Alphabettext zu codieren.
UTF-16 ist auch variabel lang. Zeichen werden entweder in zwei oder vier Bytes codiert. Ich verstehe den Punkt wirklich nicht. Es hat den Nachteil, dass es eine variable Länge hat, hat aber nicht den Vorteil, dass es so viel Platz spart wie UTF-8.
Von diesen dreien ist UTF-8 eindeutig am weitesten verbreitet.
quelle
Abhängig von Ihrer Entwicklungsumgebung haben Sie möglicherweise nicht einmal die Wahl, welche Codierung Ihres String-Datentyps intern verwendet wird.
Aber zum Speichern und Austauschen von Daten würde ich immer UTF-8 verwenden, wenn Sie die Wahl haben. Wenn Sie hauptsächlich über ASCII-Daten verfügen, erhalten Sie die kleinste zu übertragende Datenmenge, während Sie dennoch alles codieren können. Die Optimierung auf die geringste E / A ist der Weg zu modernen Maschinen.
quelle
Wie bereits erwähnt, besteht der Unterschied hauptsächlich in der Größe der zugrunde liegenden Variablen, die jeweils größer werden, damit mehr Zeichen dargestellt werden können.
Schriftarten, Codierungen und Dinge sind jedoch (unnötig?) Unglaublich kompliziert, sodass ein großer Link erforderlich ist, um mehr Details zu erhalten:
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 viel wie möglich zu lernen, so früh wie möglich (oder einfach jemanden zu beauftragen, es für Sie zu klären).
Paul.
quelle
Kurz gesagt, der einzige Grund für die Verwendung von UTF-16 oder UTF-32 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 diese für Web- / Programmierzwecke offensichtlich effizienter ist.
Ein häufiges Missverständnis - die angehängte Nummer ist KEIN Hinweis auf ihre Fähigkeit. Sie alle unterstützen den vollständigen Unicode, nur dass UTF-8 ASCII mit einem einzigen Byte verarbeiten kann und somit effizienter / weniger korrupt für die CPU und das Internet ist.
Einige gute Lektüre: http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html und http://utf8everywhere.org
quelle