2016-04-01 8 views
0

Also selbst Zeichencodierung ich unterrichte, und ich habe eine vermutlich dumme Frage: Wikipedia sagtWarum BOM ist U + FE FF, anstatt U + FF FE?

Die Bytereihenfolgemarkierung (BOM) ist ein Unicode-Zeichen U + FEFF BYTE ORDER MARK (BOM), ...

, und ein Diagramm auf dieser Seite schreibt

Encoding  Representation (hexadecimal) 
UTF-8   EF BB BF 
UTF-16 (BE) FE FF 
UTF-16 (LE) FF FE 
... 

ich es ein wenig verwirrt bin. Wie ich weiß, sind die meisten Maschinen mit Intel-CPUs Little-Endian, also warum BOM ist U+FE FF für UTF-16 (BE), anstatt U+EF BB BF für UTF-8 oder U+FF FE für UTF-16 (LE)?

+2

Nun, weil U + FEFF ist ein Zeichen und U + FFEF ist nicht. Ein leerer Bereich hat die nette Eigenschaft, dass er keinen Effekt auf gerenderten Text hat, selbst wenn eine App ihn oder Fubs nicht richtig filtert, indem er Stücklisten mitten in einen Text-Stream einfügt. Sehr häufiger Fehler. –

+0

Auf Ihrem "eher als U + EF BB BF für UTF-8": ziemlich lustig, weil UTF8 keine "Byte Order Mark" benötigt. Alle Werte in einem UTF8-kodierten Text sollen genau 1 Byte lang sein, so dass es keine Chance gibt, dass Ihre Endianz falsch ist. – usr2564301

+0

@RadLexus Also benötigt UTF-8 keine BOM, um die Endianess anzuzeigen, während UTF-16 und UTF-32 tut? –

Antwort

3

Wie ich weiß, die meisten Maschinen mit Intel-CPUs sind Little-Endian

Intel-CPUs sind nicht die einzigen CPUs auf der Welt. AMD, ARM usw. Und es gibt Big-Endian-CPUs.

warum BOM ist U + FE FF für UTF-16 (BE), anstatt U + EF BB BF für UTF-8 oder U + FF FE für UTF-16 (LE)?

U+FEFF ist die Unicode-Codepunktbezeichnung. FE FF, EF BB BF, FF FE, sind dies Sequenzen von Bytes. U+ gilt nur für Unicode-Codepunktbezeichnungen, nicht für Bytes.

Der numerische Wert von Unicode-Codepoint U+FEFF ZERO WIDTH NO-BREAK SPACE (die Bezeichnung seiner offiziell, nicht U+FEFF BYTE ORDER MARK, obwohl es auch als Stückliste verwendet wird) ist 0xFEFF (65279).

Dieser in UTF-8 codierte Codepunktwert erzeugt drei 8-Bit-Codeunit-Werte 0xEF 0xBB 0xBF, die keinen Endian-Problemen unterliegen, weshalb UTF-8 keine separaten LE- und BE-Varianten hat.

Derselbe Codepunktwert, der in UTF-16 codiert ist, erzeugt einen 16-Bit-Codeunit-Wert 0xFEFF.Da es sich um einen 16-Bit-Multibyte-Wert handelt, unterliegt es bei der Interpretation als zwei 8-Bit-Bytes dem Endian, daher die Varianten LE (0xFF 0xFE) und BE (0xFE 0xFF).

Es wird nicht nur die Stückliste beeinflusst. Alle Codeunits in einer UTF-16-Zeichenfolge sind von Endian betroffen. Die BOM hilft einem Decoder, den für die Codeunits in der gesamten Zeichenfolge verwendeten Endian zu kennen.

UTF-32, das auch Multi-Byte (32-bit) -Codeunits verwendet, unterliegt ebenfalls endian und hat daher auch LE- und BE-Varianten und eine 32-Bit-BOM, um diesen Endian zu Decodern auszudrücken (0xFF 0xFE 0x00 0x00 für LE, 0x00 0x00 0xFE 0xFF für BE). Und ja, wie Sie wahrscheinlich erraten können, gibt es eine Mehrdeutigkeit zwischen der UTF-16LE-Stückliste und der UTF-32LE-Stückliste, wenn Sie nicht vorher wissen, mit welchem ​​UTF Sie es zu tun haben. Eine Stückliste soll den Endian identifizieren, daher der Name "Byte Order Mark", nicht die spezielle Kodierung (obwohl sie üblicherweise für diesen Zweck verwendet wird).

+0

Erwähnenswert ist wohl auch, dass 'U + FFFE' kein gültiger Unicode-Codepunkt ist, weshalb' U + FEFF' als Byte-Order-Marke verwendet werden kann (sonst wäre eine zuverlässige Unterscheidung nicht möglich). Und "Endian" sollte "Endianness" sein. –

+0

Ich sehe, dass U + FEFF in Unicode 3.2 als Bruchzeichen zugunsten von U + 2060 WORD JOINER für diesen Zweck veraltet war. Die Unicode-Spezifikation besagt jedoch auch, dass, wenn U + FEFF innerhalb einer Zeichenfolge angezeigt wird, diese dennoch als Unterbrecher behandelt werden sollte: "Unicode 3.2-Implementierungen sollten dieses neue Zeichen unterstützen [U + 2060] **, unterstützen aber auch ZWNBSP Semantik von U + FEFF **. * " –

+1

Haben Sie meinen Kommentar falsch gelesen? ** "U + FEFF" ** ist ein gültiges Zeichen (ZERO WIDTH NO-BREAK SPACE) und wird als Stückliste verwendet. ** 'U + FFFE' ** ist * nicht * ein gültiges Zeichen, oder ihm ist zumindest kein Name zugewiesen (siehe [UnicodeData.txt] (http://unicode.org/Public/UNIDATA/UnicodeData) .txt, eine 1.6MB Textdatei - daher kann ** 'U + FEFF' ** als Stückliste verwendet werden. Wenn Sie **' U + FFFE' ** sehen, handelt es sich wahrscheinlich um eine Byte-getauschte Stückliste , und Sie müssen die Endianess ändern, die Sie verwenden, um die Eingabe zu interpretieren. (Und "Endian" ist ein Adjektiv; "Endianness" ist das entsprechende Substantiv.) –

2

warum BOM U + FE FF für UTF-16 ist (BE)

Es ist nicht. Stückliste ist die Zeichenummer U + FEFF. Es gibt keinen Platz, es ist eine einzelne hexadezimale Zahl, alias 65279. Diese Definition hängt nicht davon ab, welche Sequenz von Bytes verwendet wird, um diese Zeichen in einer bestimmten Kodierung darzustellen.

kommt es vor, daß die hexadezimale Darstellung der Byte-Sequenz, die das Zeichen (*) in UTF-16LE codiert, 0xFE, 0xFF die gleiche Reihenfolge von Ziffern als hexadezimale Darstellung des Zeichennummer hat U+FEFF; das ist nur ein Artefakt von Big-Endianess, es stellt höchstwertigen Inhalt auf der linken Seite, genauso wie Menschen für große [Hexa] Dezimalzahlen.

(* und in der Tat jedes Zeichen in der Basic Multilingual Plane. Es wird haariger, wenn Sie über diesem Bereich gehen, da sie nicht länger fit bleiben in zwei Bytes.)