Laut Wikipedia-Artikel hat UTF-8 das folgende Format:
Erster Code Letzter Code Bytes Byte 1 Byte 2 Byte 3 Byte 4 point point Verwendet U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 07FF 2 110xxxxx 10xxxxxx U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx x bedeutet, dass dieses Bit zur Auswahl des Codepunkts verwendet wird.
Dies verschwendet zwei Bits in jedem Fortsetzungsbyte und ein Bit im ersten Byte. Warum ist UTF-8 nicht wie folgt codiert?
Erster Code Letzter Code Bytes Byte 1 Byte 2 Byte 3 point point Verwendet U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx U + 0800 U + 1FFFFF 3 110xxxxx xxxxxxxx xxxxxxxx
Es würde ein Byte sparen, wenn sich der Codepunkt außerhalb der mehrsprachigen Grundebene befindet oder wenn sich der Codepunkt im Bereich [U + 800, U + 3FFF] befindet.
Warum wird UTF-8 nicht effizienter codiert?
Antworten:
Dies geschieht, damit Sie erkennen können, wann Sie sich in der Mitte einer Multibyte-Sequenz befinden. Wenn Sie sich UTF-8-Daten ansehen
10xxxxxx
, wissen Sie , dass Sie sich in der Mitte eines Multibyte-Zeichens befinden und im Stream sichern sollten, bis entweder0xxxxxx
oder angezeigt wird11xxxxxx
. Bei Verwendung Ihres Schemas könnten die Bytes 2 oder 3 leicht zu Mustern wie entweder0xxxxxxx
oder führen11xxxxxx
Denken Sie auch daran, dass die Menge der gespeicherten Daten von der Art der zu codierenden Zeichenfolge abhängt. Bei den meisten Texten, auch bei asiatischem Text, werden bei normalem Text selten oder nie vier Byte große Zeichen angezeigt. Auch naive Einschätzungen der Menschen darüber, wie Text aussehen wird, sind oft falsch. Ich habe Text für UTF-8 lokalisiert, der japanische, chinesische und koreanische Zeichenfolgen enthält, aber es ist eigentlich Russisch, das den größten Platz einnimmt. (Da in unseren asiatischen Zeichenfolgen häufig lateinische Schriftzeichen für Eigennamen, Interpunktion usw. verwendet werden und das durchschnittliche chinesische Wort 1-3 Zeichen lang ist, während das durchschnittliche russische Wort sehr viel länger ist.)
quelle
Der offizielle Weg informiert den Decoder, wenn er sich in der Mitte des Tupels befindet, und er kann Bytes überspringen (oder rückwärts gehen), bis das Byte mit
0
oder beginnt11
. Auf diese Weise wird verhindert, dass bei einer Beschädigung eines einzelnen Bytes Datenmüll anfällt.quelle
Kurze Antwort, Ihr Vorschlag unterscheidet nicht zwischen dem ersten Byte und dem Fortsetzungsbyte.
Das Bitmuster am oberen Ende des ersten Bytes gibt an, aus wie vielen Bytes das eigentliche Zeichen besteht. Diese Muster bieten auch eine gewisse Fehlererkennung beim Parsen einer Zeichenfolge. Wenn Sie das (scheinbar) erste Byte eines Zeichens lesen und 10xxxxxx erhalten, wissen Sie, dass Sie nicht synchron sind.
quelle
Was nicht erwähnt wurde, ist, dass Sie mit UTF-8 den Zeiger auf das erste Byte sehr leicht finden können, wenn Sie eine korrekte Sequenz von Codepunkten und einen Zeiger haben, der garantiert auf das erste Byte zeigt des vorherigen Codepunkts (überspringen Sie alle Bytes, die mit 01xx xxxx beginnen). Mit Ihrer Codierung ist es unmöglich, ohne potenziell alle Bytes bis zum Anfang der Zeichenfolge zu untersuchen.
Betrachten Sie die Folgen von (2n + 2) Bytes
und
Wenn Sie nach dieser Sequenz einen Zeiger auf das erste Byte des ersten Codepunkts haben, müssen Sie alle Bytes untersuchen, um festzustellen, ob der letzte Codepunkt 0xxxxxxx oder (10xxxxxx, 0xxxxxxx) ist.
Es gibt tatsächlich effizientere Codierungsschemata, bei denen das Wechseln zum vorherigen Codepunkt in konstanter Zeit erfolgen kann und Zeiger auf die Mitte eines Codepunkts festgelegt werden können. Erlaube die folgenden Codes:
Wenn eines der vorherigen drei Bytes ≥ 236 ist, ist dies der Beginn einer 3-Byte-Sequenz, da es in einer gültigen 3-Byte-Sequenz keine zwei solchen Bytes geben kann. Wenn andernfalls eines der vorherigen zwei Bytes ≥ 128 ist, ist dies der Beginn einer Zwei-Byte-Sequenz. Andernfalls ist das vorherige Byte ein einzelnes Byte <128.
Das Suchen nach einer Teilzeichenfolge wird etwas schwieriger. Möglicherweise möchten Sie null Bytes ausschließen, damit eine Zeichenfolge nur dann ein Nullbyte enthält, wenn sie einen Nullcodepunkt enthält.
quelle