Nach ungültigem UTF8 suchen

8

Ich konvertiere vom UTF8-Format in den tatsächlichen Wert in Hex. Jedoch gibt es einige ungültige Sequenzen von Bytes, die ich fangen muss. Gibt es eine schnelle Möglichkeit zu überprüfen, ob ein Zeichen nicht in UTF8 in C ++ gehört?

    
Mark 02.07.2011, 03:56
quelle

2 Antworten

12

Folgen Sie den Tabellen im Unicode -Standard, Kapitel 3. (Ich habe die Unicode 5.1.0-Version des Kapitels (p103) verwendet.) war Tabelle 3-7 auf p94 der Unicode 6.0.0 Version und war auf p95 in der Unicode 6.3 Version - und es ist auf p125 der Unicode Version 8.0.0.

Die Bytes 0xC0, 0xC1 und 0xF5..0xFF können nicht in gültigem UTF-8 erscheinen. Die gültigen Sequenzen sind dokumentiert; Alle anderen sind ungültig.

Tabelle 3-7. Gut geformte UTF-8-Byte-Sequenzen

%Vor%

Beachten Sie, dass sich die Unregelmäßigkeiten im zweiten Byte für bestimmte Wertebereiche des ersten Bytes befinden. Das dritte und vierte Byte sind bei Bedarf konsistent. Beachten Sie, dass nicht jeder Codepunkt innerhalb der als gültig gekennzeichneten Bereiche zugeordnet wurde (und einige sind explizit "Nicht-Zeichen"), sodass noch mehr Validierung erforderlich ist.

Die Codepunkte U + D800..U + DBFF sind für UTF-16-High-Surrogate und U + DC00..U + DFFF sind für UTF-16-Low-Surrogate; Diese können nicht in gültigem UTF-8 erscheinen (Sie kodieren die Werte außerhalb der BMP - Basic Multilingual Plane - direkt in UTF-8), weshalb dieser Bereich als ungültig markiert ist.

Andere ausgeschlossene Bereiche (Anfangs-Byte C0 oder C1 oder Anfangs-Byte E0 gefolgt von 80..9F oder Anfangs-Byte F0 gefolgt von 80..8F) sind nicht-minimale Kodierungen. Zum Beispiel würde C0 80 U + 0000 codieren, aber das ist durch 00 kodiert, und UTF-8 definiert, dass die nicht-minimale Kodierung C0 80 ungültig ist. Und der maximale Unicode-Codepunkt ist U + 10FFFF; UTF-8-Kodierungen ab F4 90 generieren Werte, die außerhalb des Bereichs liegen.

    
Jonathan Leffler 02.07.2011, 04:20
quelle
4

Gute Antwort schon, ich bin gerade dabei, eine weitere Einstellung zum Spaß zu machen.

UTF-8 verwendet ein allgemeines Schema von Prosser und Thompson, um große Zahlen in Einzelbyte-Sequenzen zu codieren. Dieses Schema kann tatsächlich 2 ^ 36 Werte darstellen, aber für Unicode benötigen wir nur 2 ^ 21. So funktioniert das. Sei N die Nummer, die du kodieren willst (z. B. ein Unicode-Codepunkt):

  • Wenn N & lt; 128, nur ein Byte 0nnnnnnn . Das höchste Bit ist Null.
  • Ansonsten mehrere Bytes. Das erste Byte beginnt mit so vielen wie es Bytes in der Sequenz gibt, gefolgt von einer Null und dann den Datenbits; aufeinander folgende Bytes beginnen mit 10 , gefolgt von sechs Datenbits. Beispiele:
  • 3-Byte-Sequenz: 1110xxxx 10xxxxxx 10xxxxxx .
  • 5-Byte-Sequenz: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx .
  • 7-Byte-Sequenz: 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx .

Eine k -Byte-Sequenz passt 5 k + 1 Bit (wenn k & gt; 1), so dass Sie bestimmen können, wie viele Bytes Sie benötigen N. Zum Dekodieren ein Byte lesen; Wenn das oberste Bit Null ist, speichern Sie den Wert so, wie er ist. Verwenden Sie andernfalls das erste Byte, um herauszufinden, wie viele Bytes sich in der Sequenz befinden, und verarbeiten Sie all diese.

Für Unicode ab heute brauchen wir höchstens k = 4 Bytes.

    
Kerrek SB 02.07.2011 08:14
quelle

Tags und Links