Beziehung zwischen Unicode und UTF-8/16/32

910
Tyler Durden

Ich verstehe die Beziehung zwischen UTF-8 und seinen anderen Varianten nicht und erhalte anomale Ergebnisse am Terminal. Zum Beispiel lautet der rechte Pfeil:

0xE2 0x86 0x92 in UTF-8

aber es ist

0x2192 in UTF-16 in UTF-16 und Unicode

Ich verstehe nicht, wie E28692 2192 entspricht.

Die UTF-8-Version scheint auch in meinem Linux-Terminal nicht zu funktionieren, das die UTF-8-Codierung mit DejaVu-Schrift verwendet, die Unicode unterstützt. Zum Beispiel, wenn ich eintrete

echo -e "\u2192"

Dann bekomme ich einen Pfeil, großartig, richtig, es funktioniert. Aber wenn ich eintrete

echo -e "\xe2\x86\x92" oder

echo -e "\x00\x00\x21\x92"

Dann bekomme ich eine falsche Grafik. Warum sind meine Hex-Sequenzen falsch?

1
Sie verwechseln den Zeichensatz und die Kodierung, um die Zeichen dieses Zeichensatzes zu kodieren [Absolutes Minimum Jeder Softwareentwickler muss unbedingt Unicode und Zeichensätze kennen (keine Ausreden!) (Http://www.joelonsoftware.com/articles/Unicode) .html) phuclv vor 10 Jahren 1
https://stackoverflow.com/questions/222386/what-do-i-need-to-know-about-unicode phuclv vor 10 Jahren 1
"Ich verstehe nicht, wie E28692 2192 entspricht." Diese Aussage ist ungültig. Das Problem ist, dass das eine * dem * nicht * gleich * ist, sondern das eine ** dem anderen ** zugeordnet ist. Leider habe ich auch noch keine Ahnung, ob es irgendeine formelartige Mapping-Funktion gibt oder ob es sich nur um eine riesige Nachschlagetabelle handelt. Nach allem, was ich sagen kann, scheint es eine gewisse Logik zu haben (https://tools.ietf.org/html/rfc3629#section-4) (wenn auch nicht nett, einfach). Synetech vor 8 Jahren 0

2 Antworten auf die Frage

2
gronostaj

Unicode ist ein Zeichensatz. UTF sind Kodierungen.

Unicode definiert eine Menge von Zeichen mit entsprechenden Codepunkten, z. Werte, die eindeutig Zeichen im Unicode-Zeichensatz identifizieren.

Zum Beispiel entspricht unicode-table.com U+0041 der Hauptstadt A, U+03A3ist griechische Hauptstadt Sigma (Σ) und U+2603ist ein Schneemann (). U+Zahlen sind Codepunkte. Unicode sagt uns, welches Symbol welchem ​​Codepunkt entspricht, aber nicht, wie diese Codepunkte in Byte zu codieren sind.

Hier kommt das UTF (Unicode Transformation Format) ins Spiel. UTF ist eine Codierung: Es ordnet Unicode-Codepunkte eindeutigen Byte-Sequenzen zu.

  • UTF-32 ist die "dumme" Kodierung. Alle Unicode-Codepunkte sind höchstens 4 Byte lang, sodass UTF-32 den Codepunkt einfach als 4-Byte-Zahl (32-Bit, daher der Name) mit der Big-Endian-Byte-Reihenfolge interpretiert . So U+2603wird als verschlüsselt 0x00002603.

    UTF-32 ist sehr einfach, aber auch sehr redundant. Die am häufigsten verwendeten Zeichen liegen im ASCII-Bereich und werden in Unicode durch die Codepunkte 0-127 dargestellt. In UTF-32-kodierten Dateien sind fast 3 von 4 Bytes Nullen. Nahezu jeder englische Satz wird 4-mal länger (in Bytes), wenn er anstelle von ASCII in UTF-32 codiert wird.

  • UTF-8 (im Internet sehr verbreitet) verwendet nur 1 Byte für ASCII-Zeichen, sodass in ASCII-Dateien kein Overhead entsteht (jede ASCII-Datei ist auch eine UTF-8-Datei mit demselben Inhalt). Andere Zeichen benötigen bis zu 6 Byte.

  • UTF-16 (nur von Windows verwendet, um nur ein Beispiel zu nennen) ist ein Kompromiss zwischen UTF-32 und UTF-8. Codepunkte werden entweder in 16-Bit- oder 32-Bit-Sequenzen codiert. In den meisten Fällen ist es redundanter als UTF-8, aber einfacher zu warten und schneller zu verarbeiten.

Unterschiedliche Zeichen können in unterschiedlichen UTF-x-Kodierungen unterschiedliche Darstellungen enthalten. Zum Beispiel können UTF-8-Sequenzen bis zu 6 Bytes umfassen, während UTF-16-Sequenzen höchstens 4 Bytes lang sind, obwohl beide denselben Zeichensatz (Unicode) codieren. Feinere Codierungen (UTF-8) verwenden mehr Bits, um die Sequenzlänge anzugeben. Daher sind codierte Werte für hohe Codepunkte länger und weniger optimal.

Die Antwort von dsolimano erklärt das Verhalten Ihrer Muschel.

Tatsächlich ist UTF-8 für alle Unicode-Codepunkte höchstens 4 Byte lang. Eine 5- oder 6-Byte-Sequenz wird verwendet, um Werte mit mehr als 21 Bit zu codieren phuclv vor 10 Jahren 0
1
dsolimano

In UTF-8 codierte Unicode-Codepunkte

Sie sind aufgrund von https://en.wikipedia.org/wiki/UTF-8#Description gleichwertig. Weitere Informationen finden Sie im Algorithmus zum Konvertieren von Unicode-Codepunkten in UTF-8. Es geht so.

Ihr Codepunkt 0x2192 liegt zwischen U + 0800 und U + FFFF. Wir verwenden also die dritte Zeile der Tabelle.

 Byte 1 Byte 2 Byte 3 16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx 

0x2192 in binär ist 0010 0001 1001 0010. Stecken wir das ein und wandeln sie dann wieder in Hex um

16 U+0800 U+FFFF 3 11100010 10000110 10010010 3 E 2 8 6 9 2 

Mit anderen Worten: E28692.

Escape-Sequenzen in Ihrer Shell

Nun, warum Ihre Shell nicht den rechten Pfeil anzeigt, wenn Sie eine UTF-8-Sequenz eingeben, schauen wir uns das Bash-Handbuch an . Suchen Sie nach dem Abschnitt über die Escape - Sequenz \xHHund Sie werden fint es beschrieben als

das Acht-Bit-Zeichen, dessen Wert der Hexadezimalwert HH ist (eine oder zwei Hexadezimalstellen)

Sie bitten bash also, drei getrennte Sequenzen mit zwei Zeichen anzuzeigen, die Ihnen wahrscheinlich etwas wie LATIN SMALL LETTER A MIT CIRCUMFLEX, START OF SELECTED AREA und einen privaten Charakter geben .

Wenn ich also den UTF-8-Code in das UTF-8-Terminal eingeben möchte, wie kann ich das tun? Tyler Durden vor 10 Jahren 0
Ich denke nicht, dass Sie dies mit einem Echo tun können, wenn Sie der Dokumentation nachgehen. dsolimano vor 10 Jahren 0