487 Stimmen

Was sind Unicode, UTF-8 und UTF-16?

Was ist die Grundlage für Unicode und warum braucht man UTF-8 oder UTF-16? Ich habe das bei Google recherchiert und auch hier nachgeschaut, aber es ist mir nicht klar.

Sur VSS Wenn Sie einen Dateivergleich durchführen, erscheint manchmal die Meldung, dass die beiden Dateien unterschiedliche UTFs haben. Warum sollte dies der Fall sein?

Bitte erklären Sie das in einfachen Worten.

677voto

DPenner1 Punkte 9618

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:

95voto

wengeezhang Punkte 2639
  • Unicode
    • ist eine Reihe von Zeichen, die auf der ganzen Welt verwendet werden
  • UTF-8
    • eine Zeichenkodierung, die in der Lage ist, alle möglichen Zeichen (so genannte Codepunkte) in Unicode zu kodieren.
    • Code-Einheit: 8 Bits
    • ein bis vier Codeeinheiten zur Kodierung von Unicode verwenden
    • 00100100 für " $ " (ein 8-Bit); 11000010 10100010 für " ¢ " (zwei 8-Bits); 11100010 10000010 10101100 für " " (drei 8-Bits)
  • UTF-16
    • eine andere Zeichenkodierung
    • Code-Einheit: 16 Bits
    • Verwendung von ein bis zwei Codeeinheiten zur Kodierung von Unicode
    • 00000000 00100100 für " $ " (ein 16-Bit); 11011000 01010010 11011111 01100010 für " " (zwei 16-Bits)

35voto

Neuron Punkte 505

Unicode ist ein ziemlich komplexer Standard. Haben Sie nicht zu viel Angst, aber seien Sie auf etwas Arbeit vorbereitet sein! [2]

Da man immer eine glaubwürdige Quelle braucht, der offizielle Bericht aber sehr umfangreich ist, empfehle ich die Lektüre des folgenden Textes:

  1. Das absolute Minimum, das jeder Softwareentwickler unbedingt über Unicode und Zeichensätze wissen muss (keine Ausreden!) Eine Einführung von Joel Spolsky, CEO von Stack Exchange.
  2. Zur BMP und darüber hinaus! Ein Tutorial von Eric Muller, damals Technischer Direktor, später Vizepräsident, beim Unicode-Konsortium (die ersten 20 Folien und Sie sind fertig)

Eine kurze Erklärung:

Computer lesen Bytes und Menschen lesen Zeichen, daher verwenden wir Kodierungsstandards um Zeichen auf Bytes abzubilden. ASCII war der erste weit verbreitete Standard, deckt aber nur lateinische Zeichen ab (sieben Bits/Zeichen können 128 verschiedene Zeichen darstellen). Unicode ist ein Standard mit dem Ziel, alle möglichen Zeichen in der Welt abzudecken (kann bis zu 1.114.112 Zeichen enthalten, d. h. maximal 21 Bits/Zeichen). Der aktuelle Unicode 8.0 enthält insgesamt 120.737 Zeichen, und das ist alles).

Der Hauptunterschied besteht darin, dass ein ASCII-Zeichen in ein Byte (acht Bits) passen kann, die meisten Unicode-Zeichen jedoch nicht. Daher werden Kodierungsformen/-schemata (wie UTF-8 und UTF-16) verwendet, und das Zeichenmodell sieht folgendermaßen aus:

Jedes Zeichen hat eine aufgezählte Position von 0 bis 1,114,111 (hex: 0-10FFFF), die als _Codepunkt_ .
Eine Kodierungsform ordnet einen Codepunkt einer Folge von Codeeinheiten zu. A Code-Einheit ist die Art und Weise, wie die Zeichen im Speicher organisiert werden sollen: 8-Bit-Einheiten, 16-Bit-Einheiten und so weiter. UTF-8 verwendet ein bis vier Einheiten von acht Bit, und UTF-16 verwendet ein oder zwei Einheiten von 16 Bit, um den gesamten Unicode von maximal 21 Bit abzudecken. Für Einheiten werden Präfixe verwendet, damit Zeichengrenzen erkannt werden können, und mehr Einheiten bedeuten mehr Präfixe, die Bits belegen. So verwendet UTF-8 zwar ein Byte für die lateinische Schrift, benötigt aber drei Bytes für spätere Schriften innerhalb einer Basic Multilingual Plane während UTF-16 für alle diese Angaben zwei Bytes verwendet. Und das ist ihr Hauptunterschied.
Schließlich ist ein Kodierungsschema (wie UTF-16BE oder UTF-16LE) ordnet (serialisiert) eine Code-Unit-Sequenz einer Byte-Sequenz zu.

Charakter:
Codepunkt: U+03C0
Kodierungsformen (Codeeinheiten):
      UTF-8: CF 80
      UTF-16: 03C0
Kodierungsschemata (Bytes):
      UTF-8: CF 80
      UTF-16BE: 03 C0
      UTF-16LE: C0 03

Tipp: Eine Hexadezimalziffer steht für vier Bits, eine zweistellige Hexadezimalzahl also für ein Byte.
Werfen Sie auch einen Blick auf Flugzeugkarten auf Wikipedia um ein Gefühl für das Layout des Zeichensatzes zu bekommen.

33voto

InGeek Punkte 2212

Der Artikel Was jeder Programmierer unbedingt über Kodierungen und Zeichensätze wissen muss, um mit Text arbeiten zu können erklärt alle Einzelheiten.

Schreiben in den Puffer

wenn Sie in einen 4-Byte-Puffer schreiben, das Symbol mit UTF8-Kodierung sieht Ihre Binärdatei wie folgt aus:

00000000 11100011 10000001 10000010

wenn Sie in einen 4-Byte-Puffer schreiben, das Symbol mit UTF16-Kodierung sieht Ihre Binärdatei wie folgt aus:

00000000 00000000 00110000 01000010

Je nachdem, welche Sprache Sie in Ihrem Inhalt verwenden, wirkt sich dies entsprechend auf Ihr Gedächtnis aus.

Beispiel: Für dieses spezielle Symbol: Die UTF16-Kodierung ist effizienter, da wir 2 freie Bytes für das nächste Symbol verwenden können. Aber das bedeutet nicht, dass Sie UTF16 für das japanische Alphabet verwenden müssen.

Lesen aus dem Puffer

Wenn Sie nun die obigen Bytes lesen wollen, müssen Sie wissen, in welcher Kodierung sie geschrieben wurden, und sie korrekt zurückdekodieren.

z.B. Wenn Sie dies entschlüsseln : 00000000 11100011 10000001 10000010 in die UTF16-Kodierung umzuwandeln, erhalten Sie no

Nota: Kodierung und Unicode sind zwei verschiedene Dinge. Unicode ist die große (Tabelle) wobei jedes Symbol einem eindeutigen Codepunkt zugeordnet ist, z. B. Symbol (Buchstabe) hat ein (Codepunkt) : 30 42 (hex). Bei der Kodierung hingegen handelt es sich um einen Algorithmus, der Symbole bei der Speicherung in Hardware in eine geeignetere Form umwandelt.

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.

30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.

Enter image description here

22voto

dan04 Punkte 82011

Ursprünglich war für Unicode eine 16-Bit-Kodierung mit fester Breite vorgesehen ( UCS-2 ). Frühe Anwender von Unicode, wie Java und Windows NT, bauten ihre Bibliotheken auf 16-Bit-Strings auf.

Später wurde der Geltungsbereich von Unicode auf historische Zeichen erweitert, was mehr als die 65 536 Codepunkte einer 16-Bit-Kodierung erfordern würde. Damit die zusätzlichen Zeichen auf Plattformen dargestellt werden können, die UCS-2 verwendet hatten, wurde die UTF-16-Kodierung eingeführt. Sie verwendet "Surrogatpaare", um Zeichen in den zusätzlichen Ebenen darzustellen.

In der Zwischenzeit verwendeten viele ältere Software und Netzwerkprotokolle 8-Bit-Strings. UTF-8 wurde entwickelt, damit diese Systeme Unicode unterstützen können, ohne breite Zeichen verwenden zu müssen. Es ist rückwärtskompatibel mit 7-Bit-ASCII.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X