Vergleich von Unicode -Codierungen
Dieser Artikel vergleicht Unicode Codierungen. Zwei Situationen werden berücksichtigt: 8-Bit-Reinigung Umgebungen (die angenommen werden können) und Umgebungen, die den Einsatz verbieten Byte Werte, die das hohe Bit eingestellt haben. Ursprünglich waren solche Verbote Links zuzulassen, die nur sieben Datenbits verwendeten, sie bleiben jedoch in einigen Standards und daher müssen einige serienmäßige Software Nachrichten generieren, die den Einschränkungen entsprechen. Standardkomprimierungsschema für Unicode und Binär geordnete Komprimierung für Unicode werden von den Vergleichstabellen ausgeschlossen, da es schwierig ist, ihre Größe einfach zu quantifizieren.
Kompatibilitätsprobleme
A UTF-8 Datei, die nur enthält ASCII Zeichen sind identisch mit einer ASCII -Datei. Legacy-Programme können im Allgemeinen UTF-8-codierte Dateien verarbeiten, auch wenn sie Nicht-ASCII-Zeichen enthalten. Zum Beispiel die C printf Funktion kann eine UTF-8-Zeichenfolge drucken, da sie nur nach dem ASCII-%-Zeichen für die Definition einer Formatierungszeichenfolge sucht, und alle anderen Bytes unverändert druckt, daher werden Nicht-ASCII-Zeichen unverändert ausgegeben.
UTF-16 und UTF-32 sind mit ASCII -Dateien unvereinbar und erfordern somit Unicode-Weichungsprogramme zum Anzeigen, Drucken und Manipulieren, auch wenn bekannt ist, dass die Datei nur Zeichen in der ASCII -Teilmenge enthält. Da sie viele Null -Bytes enthalten, können die Saiten nicht durch Normalen manipuliert werden NULL-terminierte Zeichenfolge Umgang mit sogar einfachen Operationen wie Kopie.[a]
Daher auch in den meisten UTF-16-Systemen wie z. Fenster und Java, UTF-16-Textdateien sind nicht üblich; ältere 8-Bit-Kodierungen wie ASCII oder ISO-8859-1 werden immer noch verwendet, auf Unicode -Unterstützung; oder UTF-8 wird für Unicode verwendet. Ein seltenes Gegenbeispiel ist die "Zeichenfolgen" -Datei, die von verwendet wird Mac OS X (10.3 und später) Anwendungen für die Suche nach internationalisierten Versionen von Nachrichten, die standardmäßig UTF-16 stammen, wobei "Dateien, die mit UTF-8 codiert sind ... nicht garantiert werden".[1]
Xml ist standardmäßig als UTF-8 codiert[zweifelhaft ]und alle XML-Prozessoren müssen mindestens UTF-8 (einschließlich US-ASCII per Definition) und UTF-16 unterstützen.[2]
Effizienz
UTF-8 benötigt 8, 16, 24 oder 32 Bit (eins bis vier Bytes) ein Unicode -Zeichen zu codieren, UTF-16 erfordert entweder 16 oder 32 Bit, um ein Zeichen zu codieren, und UTF-32 erfordert immer 32 Bit, um ein Zeichen zu codieren. Der erste 128 Unicode CodepunkteU+0000 bis u+007f, verwendet für die C0 -Steuerelemente und Basic Latein Zeichen und die eins zu eins ihren ASCII-Code-Äquivalenten entsprechen, werden mit 8 Bits in UTF-8, 16 Bit in UTF-16 und 32 Bit in UTF-32 codiert.
Die nächsten 1.920 Zeichen, U+0080 bis U+07ff (umfasst den Rest von fast allen Latein-Skriptalphabete, und auch griechisch, kyrillisch, koptisch, Armenisch, hebräisch, Arabisch, Syrien, Tāna und N'ko), benötigen 16 Bit, um sowohl in UTF-8 als auch in UTF-16 und 32 Bit in UTF-32 zu codieren. Für u+0800 bis u+ffff, d. H. Der Rest der Zeichen in der Grundlegende mehrsprachige Ebene (BMP, Ebene 0, U+0000 bis U+FFFF), das den Rest der Charaktere der meisten lebenden Sprachen der Welt umfasst. UTF-8 benötigt 24 Bit, um einen Charakter zu codieren, während UTF-16 16 Bits und UTF benötigt -32 benötigt 32. Codepunkte U+010000 bis U+10ffff, die Zeichen in der darstellen ergänzende Ebenen (Flugzeuge 1–16) erfordern 32 Bit in UTF-8, UTF-16 und UTF-32.
Alle druckbaren Zeichen in UTF-EBCDIC Verwenden Sie mindestens so viele Bytes wie in UTF-8 und verwenden die meisten mehr, da eine Entscheidung getroffen wurde, um die C1-Steuercodes als einzelne Bytes zu codieren. Für sieben-Bit-Umgebungen, UTF-7 ist platz effizienter als die Kombination anderer Unicode -Codierungen mit zitiert oder Basis64 Für fast alle Arten von Text (siehe "Sieben-Bit-Umgebungen" unter).
Speicherauslastung
Jedes Format hat seine eigenen Vor- und Nachteile in Bezug auf die Speicherungseffizienz (und damit auch der Übertragungszeit) und der Verarbeitungseffizienz. Die Speicherungseffizienz unterliegt dem Standort innerhalb des Unicode Coderaum in denen die Charaktere eines bestimmten Textes vorwiegend von stammen. Da Unicode -Code -Raumblöcke nach Zeichensatz (d. H. Alphabet/Skript) organisiert sind, hängt die Speicherungseffizienz eines bestimmten Textes effektiv von der Alphabet/Skript für diesen Text verwendet. Zum Beispiel benötigt UTF-8 für die 128 Codepunkte zwischen U+0000 und U+007F ein Byte weniger pro Charakter (8 gegenüber 16 Bit) als UTF-16, benötigt jedoch ein Byte pro Zeichen mehr (24 gegenüber 16 Bit ) Für die 63.488 Codepunkte zwischen U+0800 und U+FFFF. Wenn es im Bereich u+0000 bis u+007F mehr Zeichen gibt als im Bereich U+0800 bis U+FFFF, ist UTF-8 effizienter, wenn es weniger gibt, ist UTF-16 mehr effizient. Wenn die Zählungen gleich sind, sind sie genau die gleiche Größe. Ein überraschendes Ergebnis ist, dass reale Dokumente, die in Sprachen geschrieben wurden, die Charaktere nur im hohen Bereich verwenden Akronyme mit lateinischen Briefen geschrieben.
Verarbeitungszeit
In Bezug auf die Verarbeitungszeit ist der Text mit Codierung mit variabler Länge wie UTF-8 oder UTF-16 schwieriger zu verarbeiten, wenn die einzelnen Codeeinheiten ermittelt werden müssen, anstatt mit Sequenzen von Codeeinheiten zu arbeiten. Die Suche wird nicht beeinflusst, ob die Zeichen variabler Größe haben, da eine Suche nach einer Abfolge von Codeeinheiten nicht um die Spaltungen sucht (es erfordert, dass die Codierung selbstsynchronisiert wird, die sowohl UTF-8 als auch UTF-16 sind). Ein allgemeines Missverständnis ist, dass es notwendig ist, das zu finden nth Charakter "und dass dies eine Codierung mit fester Länge erfordert; in realer Verwendung der Zahl jedoch real n wird nur aus der Untersuchung der abgeleitet n - 1 Zeichen, so dass ein sequentieller Zugriff ohnehin benötigt wird. UTF-16BE und UTF-32BE sind Big-Endian, UTF-16LE und UTF-32LE sind Little-Endian. Wenn Zeichensequenzen in einer endianischen Reihenfolge auf eine Maschine mit einer anderen endianischen Reihenfolge geladen werden, müssen die Zeichen konvertiert werden, bevor sie effizient verarbeitet werden können, es sei denn, Daten werden mit einer Byte-Granularität verarbeitet (wie für UTF-8 erforderlich). Dementsprechend ist das vorliegende Problem für das Protokoll und die Kommunikation relevanter als für eine rechnerische Schwierigkeit.
Verarbeitungsprobleme
Für die Verarbeitung sollte ein Format leicht zu suchen, abschneiden und allgemein sicher verarbeiten zu können. Alle normalen Unicode -Codierungen verwenden eine Form der Codeeinheit fester Größen. Abhängig vom Format und des Codepunkts, das codiert werden soll Codepunkt. Um eine einfache Suche und Kürzung zu ermöglichen, darf eine Sequenz nicht innerhalb einer längeren Sequenz oder über die Grenze von zwei anderen Sequenzen auftreten. UTF-8, UTF-16, UTF-32 und UTF-EBCDIC haben diese wichtigen Eigenschaften aber UTF-7 und GB 18030 unterlassen Sie.
Zeichen für feste Größe können hilfreich sein, aber selbst wenn es eine feste Byte-Anzahl pro Codespunkt gibt (wie in UTF-32), gibt es kein festes Byte-Zähler pro angezeigter Zeichen zu aufgrund Charaktere kombinieren. In Anbetracht dieser Inkompatibilitäten und anderer Macken zwischen verschiedenen Codierungsschemata, der Verarbeitung von Unicode -Daten mit demselben (oder kompatiblen) Protokoll über und über die Schnittstellen (z. B. unter Verwendung einer API/Bibliothek, die Bearbeitung von Unicode -Zeichen im Client/Server -Modell usw.) kann Can im Allgemeinen verarbeitet werden. Vereinfachen Sie die gesamte Pipeline und beseitigen gleichzeitig eine potenzielle Fehlerquelle.
UTF-16 ist beliebt, da viele APIs bis zu dem Zeitpunkt, als Unicode 16-Bit-feste Breite war (als UCS-2 bezeichnet) war. Die Verwendung von UTF-16 macht jedoch Zeichen außerhalb der Grundlegende mehrsprachige Ebene Ein Sonderfall, der das Risiko von Versehen erhöht, die sich auf ihre Handhabung beziehen. Programme, die Surrogate-Paare misshandeln, haben wahrscheinlich auch Probleme mit der Kombination von Sequenzen. Die Verwendung von UTF-32 ist daher unwahrscheinlich, dass es das allgemeinere Problem der schlechten Handhabung von Multi-Code-Einheiten-Charakteren löst.
Wenn gespeicherte Daten in UTF-8 (z. B. Dateiinhalt oder Namen) sind, ist es sehr schwierig, ein System zu schreiben, das UTF-16 oder UTF-32 als API verwendet. Dies ist auf die oft übersehene Tatsache zurückzuführen, dass das von UTF-8 verwendete Byte-Array physikalisch ungültige Sequenzen enthalten kann. Beispielsweise ist es unmöglich, einen ungültigen UTF-8-Dateinamen mit einer UTF-16-API zu beheben, da keine mögliche UTF-16-String in diesen ungültigen Dateinamen übersetzt wird. Das Gegenteil ist nicht wahr: Es ist trivial, ungültige UTF-16 in eine eindeutige (wenn auch technisch ungültige) UTF-8-Zeichenfolge zu übersetzen, sodass eine UTF-8-API sowohl UTF-8- als auch UTF-16-Dateien und Namen steuern kann, was UTF erstellt -8 in einer solchen gemischten Umgebung bevorzugt. Eine unglückliche, aber weitaus häufigere Problemumgehung, die von UTF-16-Systemen verwendet wird CP-1252 und ignoriere die Mojibake Für alle nicht-ASCII-Daten.
Für Kommunikation und Speicher
UTF-16 und UTF-32 haben nicht Endiangess Definiert, daher muss eine Byte-Bestellung ausgewählt werden, wenn sie über ein byteorientiertes Netzwerk empfangen oder sie von einem byteorientierten Speicher gelesen werden. Dies kann durch Verwendung a erreicht werden Byte-Order-Marke Zu Beginn des Textes oder der Annahme von Big-Endian (RFC 2781). UTF-8, UTF-16BE, UTF-32BE, UTF-16LE und UTF-32LE sind auf einer einzigen Byte -Bestellung standardisiert und haben dieses Problem nicht.
Wenn der Bytestrom unterliegt Korruption Dann erholen sich einige Codierungen besser als andere. UTF-8 und UTF-EBCDIC sind in dieser Hinsicht am besten, da sie zu Beginn des nächsten Codepunkts nach einem korrupten oder fehlenden Byte immer wieder synchronisieren können. GB 18030 kann sich erst im nächsten ASCII-Number erholen. UTF-16 kann verarbeiten geändert Bytes, aber keine ungerade Anzahl von fehlen Bytes, die den folgenden Text übertragen werden (obwohl es ungewöhnliche und/oder nicht zugewiesene Zeichen erzeugt).[b] Wenn Bits Kann verloren gehen. Alle werden den folgenden Text verankern, obwohl UTF-8 neu synchronisiert werden kann, wenn falsche Byte-Grenzen in fast allen Texten länger als einige Bytes ungültig sind.
Im Detail
In den folgenden Tabellen werden die Anzahl der Bytes pro Codepunkt für verschiedene Unicode -Bereiche aufgeführt. Alle zusätzlichen Kommentare sind in der Tabelle enthalten. Die Zahlen gehen davon aus, dass Gemeinkosten zu Beginn und am Ende des Textblocks vernachlässigbar sind.
N.b. Die Tabellen unten listen die Nummern von Bytes pro Codepunkt, nicht pro Benutzer sichtbar "Zeichen" (oder "Graphem -Cluster"). Es kann mehrere Codepunkte erfordern, um einen einzelnen Graphem-Cluster zu beschreiben. Selbst in UTF-32 muss bei der Aufteilung oder Verkettung von Zeichenfolgen darauf geachtet werden.
Acht-Bit-Umgebungen
Codebereich (Hexadezimal) | UTF-8 | UTF-16 | UTF-32 | UTF-EBCDIC | GB 18030 |
---|---|---|---|---|---|
000000 - 00007f | 1 | 2 | 4 | 1 | 1 |
000080 - 00009f | 2 | 2 für Charaktere von geerbt von GB 2312/GBK (z. B. am meisten Chinesische Charaktere) 4 für alles andere. | |||
0000a0 - 0003ff | 2 | ||||
000400 - 0007ff | 3 | ||||
000800 - 003fff | 3 | ||||
004000 - 00ffff | 4 | ||||
010000 - 03ffff | 4 | 4 | 4 | ||
040000 - 10ffff | 5 |
Sieben-Bit-Umgebungen
Diese Tabelle deckt möglicherweise nicht jeden Sonderfall ab und sollte daher nur zur Schätzung und Vergleich verwendet werden. Um die Textgröße in einer Codierung genau zu bestimmen, siehe die tatsächlichen Spezifikationen.
Codebereich (Hexadezimal) | UTF-7 | UTF-8 zitiert- druckbar | UTF-8 Basis64 | UTF-16 Q.-P. | UTF-16 Base64 | GB 18030 Q.-P. | GB 18030 Basis64 |
---|---|---|---|---|---|---|---|
ASCII Grafische Zeichen (außer U+003D "=") | 1 für "Direktzeichen" (hängt von der Encodereinstellung für einige Codepunkte ab), 2 für u+002b "+", ansonsten wie für 000080 - 00ffff | 1 | 1+1⁄3 | 4 | 2+2⁄3 | 1 | 1+1⁄3 |
00003d (gleiches Zeichen) | 3 | 6 | 3 | ||||
ASCII Steuerzeichen: 000000 - 00001f und 00007f | 1 oder 3 je nach Direktheit | 1 oder 3 je nach Direktheit | |||||
000080 - 0007ff | 5 für einen isolierten Fall in einem Lauf einzelner Byte -Zeichen. Für Läufe 2+2⁄3 pro Charakter plus Polsterung, um eine ganze Anzahl von Bytes plus zwei zu machen, um den Lauf zu starten und zu beenden | 6 | 2+2⁄3 | 2–6 je nachdem, ob die Byte -Werte entkommen müssen | 4–6 für Zeichen, die von GB2312/GBK geerbt wurden (z. die meisten chinesischen Charaktere) 8 für alles andere. | 2+2⁄3 Für Zeichen, die von GB2312/GBK geerbt wurden (z. die meisten chinesischen Charaktere) 5+1⁄3 für alles andere. | |
000800 - 00ffff | 9 | 4 | |||||
010000 - 10ffff | 8 für isolierten Fall, 5+1⁄3 pro Charakter plus Polsterung an Ganzzahl plus 2 für einen Lauf | 12 | 5+1⁄3 | 8–12, je nachdem, ob die niedrigen Bytes der Ersatzstoffe entkommen müssen. | 5+1⁄3 | 8 | 5+1⁄3 |
Endiantness wirkt sich nicht auf die Größen aus (UTF-16BE und UTF-32BE haben die gleiche Größe wie UTF-16LE und UTF-32LE, beziehungsweise). Die Verwendung von UTF-32 unter zitiertem Druck ist sehr unpraktisch, führt jedoch zu 8–12 Bytes pro Codepunkt (etwa 10 Bytes im Durchschnitt), nämlich für BMP, jeder Codepunkt wird genau 6 Bytes mehr als 6 Bytes einnehmen als Der gleiche Code in zitiertem Druck/UTF-16. Base64/UTF-32 erhält 5+1⁄3 Bytes für irgendein Codepunkt.
Ein ASCII-Kontrollcharakter unter zitiertem oder utf-7 kann entweder direkt oder codiert (entkommen) dargestellt werden. Die Notwendigkeit, einem bestimmten Kontrollcharakter zu entkommen, hängt von vielen Umständen ab, aber Newlines In Textdaten werden normalerweise direkt codiert.
Kompressionsschemata
Bocu-1 und Scsu sind zwei Möglichkeiten, um Unicode -Daten zu komprimieren. Ihr Codierung stützt sich darauf, wie häufig der Text verwendet wird. Die meisten Textläufe verwenden das gleiche Skript. zum Beispiel, Latein, kyrillisch, griechisch usw. Mit dieser normalen Verwendung können viele Textläufe auf etwa 1 Byte pro Codepunkt komprimieren. Diese staatlichen Codierungen erschweren es, an einer Position einer Zeichenfolge zufällig auf Text zuzugreifen.
Diese beiden Komprimierungsschemata sind nicht so effizient wie andere Komprimierungsschemata, wie Postleitzahl oder BZIP2. Diese allgemeinen Komprimierungsschemata können längere Byt-Läufe auf nur wenige Bytes komprimieren. Das Scsu und Bocu-1 Kompressionsschemata komprimieren nicht mehr als die theoretischen 25% des als UTF-8, UTF-16 oder UTF-32 codierten Text. Andere allgemeine Komprimierungsschemata können leicht zu 10% der ursprünglichen Textgröße komprimieren. Die Allzweckschemata erfordern kompliziertere Algorithmen und längere Textbrocken für ein gutes Komprimierungsverhältnis.
Unicode Technische Note #14 Enthält einen detaillierteren Vergleich der Kompressionsschemata.
Historisch: UTF-5 und UTF-6
Vorschläge für eine UTF-5 und UTF-6 für die Internationalisierung von Domainnamen (IDN). Der UTF-5-Vorschlag verwendete a Basis 32 Codierung, wo Punycode ist (unter anderem und nicht genau) a Basis 36 Codierung. Der Name UTF-5 Für eine Codeeinheit von 5 Bit wird die Gleichung 2 erklärt5 = 32.[3] Der UTF-6-Vorschlag fügte hier eine laufende Länge zu UTF-5 hinzu 6 steht einfach für UTF-5 Plus 1.[4] Das Ietf Idn Wg nahm später die effizientere an Punycode für diesen Zweck.[5]
Nicht ernsthaft verfolgt werden
UTF-1 Ich habe nie ernsthafte Akzeptanz gewonnen. UTF-8 wird viel häufiger verwendet.
Die Nicht -ET -Codierungen UTF-9 und UTF-18 war Aprilscherz RFC Witzspezifikationen, obwohl UTF-9 ein funktionierendes Nicht-ET-Unicode-Transformationsformat ist, und UTF-18 ist eine funktionierende Nichtet-Codierung für alle nicht privaten Nutzungscodepunkte in Unicode 12 und unten, obwohl nicht für Ergänzende Bereiche für private Nutzung oder Tränke von Unicode 13 und später.
Anmerkungen
- ^ ASCII -Software nicht Die Verwendung von Nullzeichen zur Beendigung von Zeichenfolgen würde die utf-16- und utf-32-codierten Dateien korrekt verarbeiten (solche Dateien, die nur ASCII-Subset-Zeichen enthalten, werden als normales ASCII angezeigt, das mit gepolstert mit mit NULL -Charaktere), aber eine solche Software ist nicht üblich.
- ^ Ein eben Die Anzahl fehlender Bytes in UTF-16 dagegen wird höchstens einen Charakter übertragen.
Verweise
- ^ Apple Developer Connection: Internationalisierungsprogrammierungsthemen: Strings -Dateien
- ^ "Charaktercodierung in Entitäten". Extensible Markup Language (XML) 1.0 (fünfte Ausgabe). W3c. 2008.
- ^ Seng, James, UTF-5, ein Transformationsformat von Unicode und ISO 10646, 28. Januar 2000
- ^ Welter, Mark; Spolarich, Brian W. (16. November 2000). "UTF-6-Noch eine ASCII-kompatible Codierung für ID". Internettechnik-Arbeitsgruppe. Archiviert vom Original am 23. Mai 2016. Abgerufen 9. April 2016.
- ^ Historische IETF IDN WG Seite