Warum brauchen wir Unicode?
In den (nicht zu) frühen Tagen existierte nur ASCII. Dies war in Ordnung, da nur ein paar Steuerzeichen, Satzzeichen, Zahlen und Buchstaben wie in diesem Satz benötigt wurden. Leider war die heutige seltsame Welt der globalen Interkommunikation und der sozialen Medien nicht vorgesehen, und es ist nicht ungewöhnlich, Englisch, العربية, 汉语, עִבְרִית, ελληνικά und ភាសាខ្មែរ im selben Dokument zu sehen (ich hoffe, ich habe kein altes gebrochen Browser).
Nehmen wir an, Joe Average ist ein Softwareentwickler. Er besteht darauf, dass er immer nur Englisch braucht und als solches nur ASCII verwenden möchte. Dies mag für den Benutzer Joe in Ordnung sein, für den Softwareentwickler Joe jedoch nicht . Ungefähr die Hälfte der Welt verwendet nicht-lateinische Zeichen, und die Verwendung von ASCII ist für diese Menschen wohl rücksichtslos. Darüber hinaus schließt er seine Software für eine große und wachsende Wirtschaft aus.
Daher wird ein umfassender Zeichensatz mit allen Sprachen benötigt. So kam Unicode. Es weist jedem Zeichen eine eindeutige Nummer zu, die als Codepunkt bezeichnet wird . Ein Vorteil von Unicode gegenüber anderen möglichen Sätzen besteht darin, dass die ersten 256 Codepunkte mit ISO-8859-1 und damit auch mit ASCII identisch sind . Darüber hinaus kann die überwiegende Mehrheit der häufig verwendeten Zeichen in einer Region, die als Basic Multilingual Plane (BMP) bezeichnet wird, nur durch zwei Bytes dargestellt werden . Jetzt ist eine Zeichenkodierung erforderlich, um auf diesen Zeichensatz zuzugreifen, und wenn die Frage gestellt wird, werde ich mich auf UTF-8 und UTF-16 konzentrieren.
Überlegungen zum Speicher
Wie viele Bytes geben Zugriff auf welche Zeichen in diesen Codierungen?
- UTF-8:
- 1 Byte: Standard-ASCII
- 2 Bytes: Arabisch, Hebräisch, die meisten europäischen Schriften (insbesondere ohne Georgisch )
- 3 Bytes: BMP
- 4 Bytes: Alle Unicode-Zeichen
- UTF-16:
- 2 Bytes: BMP
- 4 Bytes: Alle Unicode-Zeichen
Es ist jetzt erwähnenswert, dass Zeichen, die nicht im BMP enthalten sind, alte Skripte, mathematische Symbole, Musiksymbole und seltenere chinesische / japanische / koreanische (CJK) Zeichen enthalten.
Wenn Sie hauptsächlich mit ASCII-Zeichen arbeiten, ist UTF-8 sicherlich speichereffizienter. Wenn Sie jedoch hauptsächlich mit außereuropäischen Skripten arbeiten, kann die Verwendung von UTF-8 bis zu 1,5-mal weniger speichereffizient sein als UTF-16. Wenn Sie mit großen Textmengen wie großen Webseiten oder langen Word-Dokumenten arbeiten, kann dies die Leistung beeinträchtigen.
Grundlagen der Codierung
Hinweis: Wenn Sie wissen, wie UTF-8 und UTF-16 codiert sind, fahren Sie mit dem nächsten Abschnitt für praktische Anwendungen fort.
- UTF-8: Für die Standard-ASCII-Zeichen (0-127) sind die UTF-8-Codes identisch. Dies macht UTF-8 ideal, wenn Abwärtskompatibilität mit vorhandenem ASCII-Text erforderlich ist. Andere Zeichen benötigen 2-4 Bytes. Dies erfolgt durch Reservieren einiger Bits in jedem dieser Bytes, um anzuzeigen, dass es Teil eines Mehrbytezeichens ist. Insbesondere soll das erste Bit jedes Bytes
1
einen Konflikt mit den ASCII-Zeichen vermeiden.
- UTF-16: Für gültige BMP-Zeichen ist die UTF-16-Darstellung einfach der Codepunkt. Für Nicht-BMP-Zeichen führt UTF-16 jedoch Ersatzpaare ein . In diesem Fall wird eine Kombination aus zwei Zwei-Byte-Abschnitten einem Nicht-BMP-Zeichen zugeordnet. Diese Zwei-Byte-Teile stammen aus dem BMP-Zahlenbereich, werden jedoch vom Unicode-Standard als ungültig als BMP-Zeichen garantiert. Da UTF-16 zwei Bytes als Grundeinheit hat, ist es außerdem von Endianness betroffen . Zum Ausgleich kann ein reserviertes Byte-Bestellzeichen am Anfang eines Datenstroms platziert werden, das die Endianität anzeigt. Wenn Sie also die UTF-16-Eingabe lesen und keine Endianness angegeben ist, müssen Sie dies überprüfen.
Wie zu sehen ist, sind UTF-8 und UTF-16 bei weitem nicht miteinander kompatibel. Wenn Sie also E / A ausführen, stellen Sie sicher, dass Sie wissen, welche Codierung Sie verwenden! Weitere Informationen zu diesen Codierungen finden Sie in den UTF-FAQ .
Praktische Überlegungen zur Programmierung
Zeichen- und Zeichenfolgendatentypen: Wie werden sie in der Programmiersprache codiert? Wenn es sich um Rohbytes handelt, können in dem Moment, in dem Sie versuchen, Nicht-ASCII-Zeichen auszugeben, einige Probleme auftreten. Auch wenn der Zeichentyp auf einer UTF basiert, bedeutet dies nicht, dass die Zeichenfolgen die richtige UTF sind. Sie können unzulässige Byte-Sequenzen zulassen. Im Allgemeinen müssen Sie eine Bibliothek verwenden, die UTF unterstützt, z. B. ICU für C, C ++ und Java. Wenn Sie etwas anderes als die Standardcodierung eingeben / ausgeben möchten, müssen Sie es in jedem Fall zuerst konvertieren.
Empfohlene / Standard- / dominante Codierungen: Wenn Sie die Wahl haben, welches UTF verwendet werden soll, ist es normalerweise am besten, die empfohlenen Standards für die Umgebung zu befolgen, in der Sie arbeiten. Beispielsweise ist UTF-8 im Web dominant und seit HTML5 wurde die empfohlene Kodierung . Umgekehrt basieren sowohl .NET- als auch Java-Umgebungen auf einem UTF-16-Zeichentyp. Verwirrenderweise (und fälschlicherweise) wird häufig auf die "Unicode-Codierung" verwiesen, die sich normalerweise auf die dominante UTF-Codierung in einer bestimmten Umgebung bezieht.
Bibliotheksunterstützung: Die von Ihnen verwendeten Bibliotheken unterstützen eine Art Codierung. Welcher? Unterstützen sie die Eckfälle? Da die Notwendigkeit die Mutter der Erfindung ist, unterstützen UTF-8-Bibliotheken im Allgemeinen 4-Byte-Zeichen ordnungsgemäß, da 1, 2 und sogar 3-Byte-Zeichen häufig auftreten können. Allerdings unterstützen nicht alle angeblichen UTF-16-Bibliotheken Ersatzpaare ordnungsgemäß, da sie sehr selten auftreten.
Zeichen zählen: In Unicode gibt es Kombinationszeichen . Beispielsweise bilden der Codepunkt U + 006E (n) und U + 0303 (eine kombinierende Tilde) ñ, aber der Codepunkt U + 00F1 bildet ñ. Sie sollten identisch aussehen, aber ein einfacher Zählalgorithmus gibt 2 für das erste Beispiel und 1 für das letztere zurück. Dies ist nicht unbedingt falsch, kann aber auch nicht das gewünschte Ergebnis sein.
Vergleich für Gleichheit: A, А und Α sehen gleich aus, aber sie sind lateinisch, kyrillisch und griechisch. Sie haben auch Fälle wie C und Ⅽ, einer ist ein Buchstabe, der andere eine römische Ziffer. Darüber hinaus müssen wir auch die kombinierenden Zeichen berücksichtigen. Weitere Informationen finden Sie unter Doppelte Zeichen in Unicode .
Ersatzpaare: Diese kommen bei SO häufig genug vor, daher werde ich nur einige Beispiellinks bereitstellen:
Andere?: