Warum brauchen wir Unicode?
In den (nicht allzu) frühen Tagen gab es nur ASCII . Das war in Ordnung, denn man brauchte nur ein paar Steuerzeichen, Satzzeichen, Zahlen und Buchstaben wie die in diesem Satz. Leider war die heutige seltsame Welt der globalen Interkommunikation und der sozialen Medien nicht vorauszusehen, und es ist nicht allzu ungewöhnlich, Englisch, , , , und im selben Dokument zu sehen (ich hoffe, ich habe keine alten Browser kaputt gemacht).
Aber nehmen wir einmal an, dass Joe Average ein Softwareentwickler ist. Er besteht darauf, dass er immer nur Englisch braucht, und möchte daher nur ASCII verwenden. Das mag für den Durchschnittsbürger in Ordnung sein. Benutzer aber das ist nicht in Ordnung für Joe, den Softwareentwickler . Ungefähr die Hälfte der Welt verwendet nicht-lateinische Schriftzeichen, und die Verwendung von ASCII ist diesen Menschen gegenüber wohl rücksichtslos, und obendrein verschließt er seine Software einer großen und wachsenden Wirtschaft.
Daher ist ein umfassender Zeichensatz mit tous Sprachen erforderlich ist. So kam Unicode . Es weist jedem Zeichen eine eindeutige Nummer zu, die als Codepunkt . Ein Vorteil von Unicode gegenüber anderen möglichen Sets ist, dass die ersten 256 Codepunkte identisch sind mit ISO-8859-1 und damit auch ASCII. Darüber hinaus ist die große Mehrheit der häufig verwendeten Zeichen durch nur zwei Bytes darstellbar, in einem Bereich, der als Basis-Mehrsprachigkeitsebene (BMP) . Für den Zugriff auf diesen Zeichensatz wird nun eine Zeichenkodierung benötigt, und da die Frage gestellt wird, werde ich mich auf UTF-8 und UTF-16 konzentrieren.
Überlegungen zum Speicher
Wie viele Bytes ermöglichen also den Zugriff auf welche Zeichen in diesen Kodierungen?
-
UTF-8:
-
1 Byte: Standard-ASCII
-
2 Bytes: Arabisch, Hebräisch, die meisten europäischen Schriften (vor allem ohne Georgisch )
-
3 Bytes: BMP
-
4 Bytes: Alle Unicode-Zeichen
-
UTF-16:
-
2 Bytes: BMP
-
4 Bytes: Alle Unicode-Zeichen
Es ist erwähnenswert, dass zu den Zeichen, die nicht im BMP enthalten sind, auch alte Schriften, mathematische Symbole, musikalische Symbole und seltenere Chinesisch, Japanisch und Koreanisch (CJK) Zeichen.
Wenn Sie hauptsächlich mit ASCII-Zeichen arbeiten, dann ist UTF-8 sicherlich speichereffizienter. Wenn Sie jedoch hauptsächlich mit außereuropäischen Schriftzeichen arbeiten, kann die Verwendung von UTF-8 bis zu 1,5 Mal weniger speichereffizient sein als UTF-16. Bei großen Textmengen, z. B. bei umfangreichen Webseiten oder langen Word-Dokumenten, kann sich dies auf die Leistung auswirken.
Grundlagen der Kodierung
Hinweis: Wenn Sie wissen, wie UTF-8 und UTF-16 kodiert werden, können Sie mit dem nächsten Abschnitt über praktische Anwendungen fortfahren.
- UTF-8: Für die Standard-ASCII-Zeichen (0-127) sind die UTF-8-Codes identisch. Damit ist UTF-8 ideal, wenn Abwärtskompatibilität mit bestehendem ASCII-Text erforderlich ist. Für andere Zeichen werden 2-4 Bytes benötigt. Dazu werden in jedem dieser Bytes einige Bits reserviert, um anzuzeigen, dass es sich um ein Multi-Byte-Zeichen handelt. Insbesondere ist das erste Bit jedes Bytes
1
um Überschneidungen mit den ASCII-Zeichen zu vermeiden.
- UTF-16: Für gültige BMP-Zeichen ist die UTF-16-Darstellung einfach ihr Codepunkt. Für Nicht-BMP-Zeichen führt UTF-16 jedoch Folgendes ein Surrogatpaare . In diesem Fall wird eine Kombination von zwei Zwei-Byte-Abschnitten einem Nicht-BMP-Zeichen zugeordnet. Diese Zwei-Byte-Abschnitte stammen aus dem numerischen BMP-Bereich, sind aber nach dem Unicode-Standard garantiert als BMP-Zeichen ungültig. Da UTF-16 zwei Bytes als Grundeinheit hat, ist es außerdem betroffen von endianness . Zum Ausgleich wird eine reservierte Byte-Order-Markierung kann an den Anfang eines Datenstroms gesetzt werden, um die Endianness anzuzeigen. Wenn Sie also eine UTF-16-Eingabe lesen und keine Endianness angegeben ist, müssen Sie dies überprüfen.
Wie man sieht, sind UTF-8 und UTF-16 nicht annähernd kompatibel zueinander. Wenn Sie also E/A durchführen, sollten Sie wissen, welche Kodierung Sie verwenden! Weitere Einzelheiten zu diesen Kodierungen finden Sie in der UTF-FAQ .
Praktische Überlegungen zur Programmierung
Zeichen- und String-Datentypen: Wie sind sie in der Programmiersprache kodiert? Wenn es sich um rohe Bytes handelt, kann es zu Problemen kommen, sobald Sie versuchen, Nicht-ASCII-Zeichen auszugeben. Auch wenn der Zeichentyp auf einem UTF basiert, bedeutet das nicht, dass die Zeichenketten dem UTF entsprechen. Sie können unzulässige Bytefolgen enthalten. Im Allgemeinen müssen Sie eine Bibliothek verwenden, die UTF unterstützt, wie z. B. INTENSIVSTATION für C, C++ und Java. Wenn Sie eine andere Kodierung als die Standardkodierung ein- oder ausgeben möchten, müssen Sie sie zuerst konvertieren.
Empfohlene, Standard- und dominante Kodierungen: Wenn Sie die Wahl haben, welche UTF Sie verwenden möchten, ist es in der Regel am besten, den empfohlenen Standards für die Umgebung, in der Sie arbeiten, zu folgen. Im Web beispielsweise ist UTF-8 vorherrschend, und seit HTML5 ist es die empfohlene Kodierung . Umgekehrt sind beide .NET y Java Umgebungen basieren auf einem UTF-16-Zeichentyp. Verwirrenderweise (und fälschlicherweise) wird oft auf die "Unicode-Kodierung" verwiesen, die sich in der Regel auf die dominante UTF-Kodierung in einer bestimmten Umgebung bezieht.
Unterstützung der Bibliothek: Die von Ihnen verwendeten Bibliotheken unterstützen irgendeine Art von Kodierung. Welche? Unterstützen sie die Eckfälle? Da Not erfinderisch macht, unterstützen UTF-8-Bibliotheken in der Regel 4-Byte-Zeichen ordnungsgemäß, da 1, 2 und sogar 3-Byte-Zeichen häufig vorkommen können. Allerdings unterstützen nicht alle angeblichen UTF-16-Bibliotheken Surrogatpaare richtig, da sie sehr selten vorkommen.
Zählen von Zeichen: Es gibt Kombination Zeichen in Unicode. Zum Beispiel bildet der Codepunkt U+006E (n) und U+0303 (eine kombinierte Tilde) n, aber der Codepunkt U+00F1 bildet ñ. Sie sollten identisch aussehen, aber ein einfacher Zählalgorithmus liefert für das erste Beispiel 2 und für das zweite 1. Das ist nicht unbedingt falsch, aber es ist auch nicht unbedingt das gewünschte Ergebnis.
Vergleiche für Gleichheit: A, , und sehen gleich aus, aber sie sind lateinisch, kyrillisch bzw. griechisch. Es gibt auch Fälle wie C und . Das eine ist ein Buchstabe, das andere eine römische Zahl. Außerdem gibt es noch die kombinierten Zeichen zu beachten. Weitere Informationen finden Sie unter _Doppelte Zeichen in Unicode_ .
Leihmutterpaare: Diese Fragen tauchen oft genug auf Stack Overflow auf, daher werde ich nur einige Beispiellinks angeben: