1141 Stimmen

Was ist der Unterschied zwischen UTF-8 und UTF-8 mit BOM?

Was ist der Unterschied zwischen UTF-8 und UTF-8 mit BOM?

89 Stimmen

UTF-8 kann besser durch Inhalte als durch BOM automatisch erkannt werden. Die Methode ist einfach: Versuchen Sie, die Datei (oder einen String) als UTF-8 zu lesen, und wenn dies gelingt, nehmen Sie an, dass die Daten UTF-8 sind. Andernfalls gehen Sie davon aus, dass es sich um CP1252 (oder eine andere 8-Bit-Codierung) handelt. Jede nicht-UTF-8-acht-Bit-Codierung wird fast sicher Sequenzen enthalten, die von UTF-8 nicht erlaubt sind. Reines ASCII (7-Bit) wird als UTF-8 interpretiert, aber das Ergebnis ist auch so korrekt.

53 Stimmen

Das Scannen großer Dateien nach UTF-8-Inhalten dauert einige Zeit. Ein BOM beschleunigt diesen Prozess erheblich. In der Praxis müssen Sie oft beides tun. Der Übeltäter heutzutage ist, dass immer noch viele Textinhalte nicht Unicode sind, und ich stoße immer noch auf Tools, die behaupten, sie würden Unicode (zum Beispiel UTF-8) verwenden, aber ihren Inhalt in einer anderen Codepage ausgeben.

11 Stimmen

@Tronic Ich denke nicht wirklich, dass "besser" in diesem Fall passt. Es kommt auf die Umgebung an. Wenn Sie sicher sind, dass alle UTF-8-Dateien mit einem BOM markiert sind, ist das Überprüfen des BOM der "bessere" Weg, da er schneller und zuverlässiger ist.

1017voto

Martin Cote Punkte 27446

Das UTF-8 BOM ist eine Sequenz von Bytes am Anfang eines Textstroms (0xEF, 0xBB, 0xBF), die es dem Leser ermöglicht, eine Datei zuverlässiger als in UTF-8 codiert zu erkennen.

Normalerweise wird das BOM verwendet, um die Byte-Reihenfolge einer Codierung zu signalisieren, aber da die Byte-Reihenfolge für UTF-8 irrelevant ist, ist das BOM unnötig.

Laut dem Unicode-Standard wird der BOM für UTF-8-Dateien nicht empfohlen:

2.6 Kodierungsschemata

... Die Verwendung eines BOM ist weder erforderlich noch empfohlen für UTF-8, kann aber in Kontexten auftreten, in denen UTF-8-Daten aus anderen Codierungsformen konvertiert werden, die ein BOM verwenden, oder wo das BOM als UTF-8-Signatur verwendet wird. Weitere Informationen finden Sie im Abschnitt "Byte Order Mark" im Unterabschnitt Abschnitt 16.8, Spezialfälle.

153 Stimmen

Es mag nicht empfohlen werden, aber aus meiner Erfahrung bei hebräischen Konvertierungen ist das BOM manchmal entscheidend für die UTF-8-Erkennung in Excel und kann den Unterschied zwischen Kauderwelsch und Hebräisch ausmachen.

54 Stimmen

Es könnte nicht empfohlen werden, aber es hat Wunder mit meinem PowerShell-Skript gemacht, als ich versuchte, "æøå" auszugeben.

83 Stimmen

Unabhängig davon, dass es nicht vom Standard empfohlen wird, ist es erlaubt, und ich ziehe es stark vor, dass etwas als UTF-8-Signatur fungiert, anstatt zu vermuten oder zu raten. Unicode-konforme Software sollte/in der Lage sein, damit umzugehen, daher ermutige ich persönlich zu dessen Verwendung.

305voto

paercebal Punkte 78198

Die anderen ausgezeichneten Antworten haben bereits beantwortet, dass:

  • Es keinen offiziellen Unterschied zwischen UTF-8 und BOM-ed UTF-8 gibt
  • Ein BOM-ed UTF-8-String wird mit den folgenden drei Bytes beginnen. EF BB BF
  • Diese Bytes müssen, wenn vorhanden, beim Extrahieren des Strings aus der Datei/dem Stream ignoriert werden.

Aber als zusätzliche Information dazu könnte der BOM für UTF-8 eine gute Möglichkeit sein, "zu erkennen", ob ein String in UTF-8 codiert wurde... Oder es könnte ein legitimer String in einer anderen Codierung sein...

Zum Beispiel könnten die Daten [EF BB BF 41 42 43] entweder sein:

Also, während es cool sein kann, die Codierung des Inhalts einer Datei anhand der ersten Bytes zu erkennen, sollte man sich darauf nicht verlassen, wie im obigen Beispiel gezeigt

Codierungen sollten bekannt sein, nicht erraten.

3 Stimmen

Entschuldigung, aber ich verstehe das Beispiel, das Sie gerade gegeben haben, nicht ganz. Wenn ich einen String [EF BB BF 41 42 43] hätte, wie könnte ich ihn interpretieren? Mit ISO-8859-1 oder UTF-8? Denn wie Ihr Beispiel sagte, werden beide eine gültige Zeichenfolge liefern: "ï »¿ABC" und "ABC".

72 Stimmen

@ Alcott: Du hast es richtig verstanden. Die Zeichenfolge [EF BB BF 41 42 43] ist nur eine Gruppe von Bytes. Sie benötigen externe Informationen, um zu entscheiden, wie sie interpretiert werden sollen. Wenn Sie glauben, dass diese Bytes mit ISO-8859-1 codiert wurden, dann ist die Zeichenfolge "ï » ¿ABC". Wenn Sie glauben, dass diese Bytes mit UTF-8 codiert wurden, dann ist es "ABC". Wenn Sie es nicht wissen, dann müssen Sie versuchen, es herauszufinden. Das BOM könnte ein Hinweis sein. Das Fehlen eines ungültigen Zeichens beim Dekodieren als UTF-8 könnte ein weiterer Hinweis sein... Letztendlich ist eine Bytefolge ohne Erinnerung an oder Wissen über die Codierung einfach eine Bytefolge.

24 Stimmen

@paercebal Während "" gültiges Latin-1 ist, ist es sehr unwahrscheinlich, dass eine Textdatei mit dieser Kombination beginnt. Das gleiche gilt für die ucs2-le/be-Marker ÿþ und þÿ. Außerdem kann man niemals sicher sein.

180voto

jpsecher Punkte 3938

Es gibt mindestens drei Probleme beim Hinzufügen eines BOM zu UTF-8 codierten Dateien.

  1. Dateien, die keinen Text enthalten, sind nicht länger leer, weil sie immer den BOM enthalten.
  2. Dateien, die Text im ASCII-Teil von UTF-8 enthalten, sind nicht mehr selbst ASCII, da der BOM nicht ASCII ist, was dazu führt, dass einige existierende Tools versagen, und es kann unmöglich für Benutzer sein, solche veralteten Tools zu ersetzen.
  3. Es ist nicht möglich, mehrere Dateien zusammenzufügen, weil jetzt jede Datei am Anfang einen BOM hat.

Und wie andere bereits erwähnt haben, ist es weder ausreichend noch notwendig, einen BOM zu haben, um festzustellen, dass etwas UTF-8 ist:

  • Es ist nicht ausreichend, weil eine beliebige Bytefolge zufällig mit der exakten Sequenz beginnen kann, die den BOM ausmacht.
  • Es ist nicht notwendig, weil man die Bytes einfach so lesen kann, als ob sie UTF-8 wären; wenn dies erfolgreich ist, ist es definitionsgemäß gültiges UTF-8.

5 Stimmen

@cheers-and-hth-alf Ich habe die obige Aussage jetzt präzisiert; es handelt sich um Fakten, ohne Logik involviert.

0 Stimmen

Nach der Bearbeitung von Punkt 1 und 2 sind diese beiden Punkte nicht mehr offensichtlich widersprüchlich. Dies ist eine Verbesserung. Ich werde jeden Punkt nacheinander besprechen.

12 Stimmen

Re Punkt 1 "Dateien, die keinen Text enthalten, sind nicht mehr leer, weil sie immer das BOM enthalten", verwirrt dies (1) das Betriebssystem-Dateisystemniveau mit dem interpretierten Inhaltsniveau und (2) geht fälschlicherweise davon aus, dass beim Verwenden des BOM auch in jeder sonst leeren Datei ein BOM stehen muss. Die praktische Lösung für (1) besteht darin, (2) nicht zu tun. Im Wesentlichen reduziert sich die Beschwerde darauf, dass es möglich ist, unnötigerweise ein BOM in eine ansonsten leere Datei zu setzen, was die einfachste Erkennung einer logisch leeren Datei (durch Überprüfen der Dateigröße) verhindert. Gute Software sollte jedoch damit umgehen können, da sie einen Zweck hat.

143voto

rsp Punkte 99616

Hier sind Beispiele für die Verwendung des BOM, die tatsächlich echte Probleme verursachen, und dennoch wissen viele Menschen nichts darüber.

BOM zerstört Skripte

Shell-Skripte, Perl-Skripte, Python-Skripte, Ruby-Skripte, Node.js-Skripte oder jede andere ausführbare Datei, die von einem Interpreter ausgeführt werden muss, beginnen alle mit einer Shebang-Zeile, die einer dieser Zeilen ähnelt:

#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node

Es sagt dem System, welcher Interpreter ausgeführt werden muss, wenn ein solches Skript aufgerufen wird. Wenn das Skript in UTF-8 codiert ist, könnte man versucht sein, am Anfang ein BOM einzufügen. Aber tatsächlich sind die "#!"-Zeichen nicht einfach nur Zeichen. Sie sind tatsächlich eine Magische Zahl, die aus zwei ASCII-Zeichen besteht. Wenn Sie etwas (wie ein BOM) vor diese Zeichen setzen, wird die Datei aussehen, als hätte sie eine andere magische Zahl, und das kann zu Problemen führen.

Sehen Sie Wikipedia, Artikel: Shebang, Abschnitt: Magische Zahl:

Die Shebang-Zeichen werden von denselben beiden Bytes in erweiterten ASCII-Codierungen dargestellt, einschließlich UTF-8, die häufig für Skripte und andere Textdateien auf aktuellen Unix-Systemen verwendet werden. Allerdings können UTF-8-Dateien mit dem optionalen Byte-Order-Mark (BOM) beginnen; wenn das "exec"-Funktion explizit die Bytes 0x23 und 0x21 erkennt, dann verhindert die Anwesenheit des BOM (0xEF 0xBB 0xBF) vor der Shebang, dass der Skriptinterpreter ausgeführt wird. Einige Behörden empfehlen, aus diesem Grund und aus Gründen der breiteren Interoperabilität und philosophischen Bedenken, die Verwendung des Byte-Order-Mark in POSIX-(Unix-ähnlichen) Skripten nicht. Darüber hinaus ist ein Byte-Order-Mark in UTF-8 nicht notwendig, da diese Codierung keine Byte-Reihenfolgeprobleme hat; er dient nur dazu, die Codierung als UTF-8 zu identifizieren. [Hervorhebung hinzugefügt]

BOM ist in JSON unzulässig

Sehen Sie RFC 7159, Abschnitt 8.1:

Implementierungen dürfen am Anfang eines JSON-Textes keinen Byte-Order-Mark hinzufügen.

BOM ist in JSON überflüssig

Es ist nicht nur unerlaubt in JSON, es ist auch nicht erforderlich, um die Zeichenkodierung zu bestimmen, da es zuverlässigere Möglichkeiten gibt, sowohl die Zeichenkodierung als auch die Byte-Reihenfolge in jedem JSON-Stream eindeutig festzulegen (siehe diese Antwort für Details).

BOM zerstört JSON-Parser

Es ist nicht nur unerlaubt in JSON und nicht erforderlich, es zerstört tatsächlich alle Software, die die Kodierung mithilfe der in RFC 4627 dargelegten Methode bestimmt:

Bestimmung der Codierung und Byte-Reihenfolge von JSON, Überprüfung der ersten vier Bytes auf das NUL-Byte:

00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8

Jetzt, wenn die Datei mit BOM beginnt, wird es so aussehen:

00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8

Beachten Sie, dass:

  1. UTF-32BE beginnt nicht mit drei NULs, daher wird es nicht erkannt
  2. UTF-32LE das erste Byte wird nicht von drei NULs gefolgt, daher wird es nicht erkannt
  3. UTF-16BE hat nur ein NUL in den ersten vier Bytes, daher wird es nicht erkannt
  4. UTF-16LE hat nur ein NUL in den ersten vier Bytes, daher wird es nicht erkannt

Abhängig von der Implementierung können alle diese fälschlicherweise als UTF-8 interpretiert und dann als fehlerhaftes UTF-8 abgelehnt werden oder überhaupt nicht erkannt werden.

Zusätzlich, wenn die Implementierung wie von mir empfohlen auf gültiges JSON überprüft, wird sie selbst die Eingabe ablehnen, die tatsächlich als UTF-8 codiert ist, da sie nicht mit einem ASCII-Zeichen < 128 beginnt, wie es nach dem RFC erforderlich ist.

Weitere Datenformate

BOM in JSON ist nicht erforderlich, ist unerlaubt und zerstört Software, die gemäß dem RFC korrekt funktioniert. Es sollte selbstverständlich sein, es einfach nicht zu verwenden, und doch gibt es immer Menschen, die darauf bestehen, JSON zu zerstören, indem sie BOMs, Kommentare, unterschiedliche Anführungsregeln oder unterschiedliche Datentypen verwenden. Natürlich kann jeder Dinge wie BOMs oder alles andere verwenden, wenn Sie es benötigen - nennen Sie es dann einfach nicht JSON.

Bei anderen Datenformaten als JSON schauen Sie, wie es tatsächlich aussieht. Wenn die einzigen Codierungen UTF-* sind und das erste Zeichen ein ASCII-Zeichen kleiner als 128 sein muss, haben Sie bereits alle Informationen, die Sie benötigen, um sowohl die Kodierung als auch die Byte-Reihenfolge Ihrer Daten zu bestimmen. Das Hinzufügen von BOMs, selbst als optionale Funktion, würde es nur komplizierter und fehleranfälliger machen.

Weitere Verwendungen von BOM

Was die Verwendung außerhalb von JSON oder Skripten betrifft, denke ich, dass es hier bereits sehr gute Antworten gibt. Ich wollte speziell mehr detaillierte Informationen zu Skripting und Serialisierung hinzufügen, da es ein Beispiel dafür ist, dass BOM-Zeichen tatsächlich echte Probleme verursachen.

7 Stimmen

Rfc7159, das rfc4627 ersetzt, schlägt tatsächlich vor, dass die Unterstützung von BOM vielleicht nicht so böse ist. Im Grunde ist das Fehlen eines BOM nur ein mehrdeutiger Trick, so dass alte Windows- und Unix-Software, die nicht Unicode-fähig sind, utf-8 immer noch verarbeiten können.

2 Stimmen

Es scheint, dass JSON aktualisiert werden muss, um es zu unterstützen, genauso wie Perl-Skripte, Python-Skripte, Ruby-Skripte, Node.js. Nur weil diese Plattformen sich entschieden haben, keine Unterstützung einzubeziehen, bedeutet das nicht zwangsläufig das Ende für BOM. Apple versucht seit einigen Jahren, Adobe zu töten, und Adobe existiert immer noch. Aber ein aufschlussreicher Beitrag.

24 Stimmen

@EricGrange, du scheinst BOM sehr stark zu unterstützen, aber erkennst nicht, dass dies das allgegenwärtige, universell nützliche, optimal-minimale "Klartext"-Format zu einer Reliquie der vor-UTF8-Vergangenheit machen würde! Das Hinzufügen von irgendwelchen Arten von (in-band) Headern zum klaren Textstrom würde, per Definition, ein obligatorisches Protokoll auf die einfachste Textdateien aufzwingen, so dass es nie wieder die "einfachste" wäre! Und wofür? Um alle anderen, alten CP-Kodierungen zu unterstützen, die auch keine Signaturen hatten, sodass man sie mit UTF-8 verwechseln könnte? (Übrigens, auch ASCII ist UTF-8. Sollte also auch ein BOM für diejenigen sein? ;) Komm schon.)

52voto

dan04 Punkte 82011

Was ist der Unterschied zwischen UTF-8 und UTF-8 ohne BOM?

Kurze Antwort: In UTF-8 wird ein BOM als die Bytes EF BB BF am Anfang der Datei kodiert.

Lange Antwort:

Ursprünglich wurde erwartet, dass Unicode in UTF-16/UCS-2 codiert wird. Der BOM wurde für diese Codierungsform entworfen. Wenn Sie 2-Byte-Codeeinheiten haben, ist es notwendig anzuzeigen, in welcher Reihenfolge diese beiden Bytes stehen, und eine gängige Konvention hierfür ist es, das Zeichen U+FEFF als "Byte Order Mark" am Anfang der Daten einzuschließen. Das Zeichen U+FFFE ist dauerhaft unzugeordnet, so dass seine Anwesenheit dazu verwendet werden kann, um die falsche Byte-Reihenfolge zu erkennen.

UTF-8 hat unabhängig von der Plattformbindeordnung die gleiche Byte-Reihenfolge, daher ist ein Byte Reihenfolgezeichen nicht erforderlich. Es kann jedoch (als die Bytefolge EF BB FF) in Daten auftreten, die von UTF-16 nach UTF-8 konvertiert wurden, oder als "Signatur", um anzuzeigen, dass die Daten UTF-8 sind.

Was ist besser?

Ohne. Wie Martin Cote beantwortete, empfiehlt der Unicode-Standard dies nicht. Es verursacht Probleme mit nicht-BOM-erkannter Software.

Ein besseres Mittel zur Erkennung, ob eine Datei UTF-8 ist, ist eine Gültigkeitsprüfung durchzuführen. UTF-8 hat strenge Regeln darüber, welche Byte-Folgen gültig sind, daher ist die Wahrscheinlichkeit eines falschen Positivs vernachlässigbar. Wenn eine Byte-Folge wie UTF-8 aussieht, ist sie es wahrscheinlich auch.

9 Stimmen

Dies würde auch gültiges UTF-8 mit einem einzigen fehlerhaften Byte ungültig machen, jedoch :/

10 Stimmen

-1 re " Es verursacht Probleme mit nicht-BOM-fähiger Software. ", das war für mich noch nie ein Problem, sondern im Gegenteil, dieses Fehlen von BOM verursacht Probleme mit BOM-fähiger Software (insbesondere Visual C++) und war ein Problem. Daher ist diese Aussage sehr plattformspezifisch, eine enge Sichtweise aus dem Unix-Bereich, wird jedoch irreführend präsentiert als würde sie allgemein gelten. Was nicht der Fall ist.

6 Stimmen

Nein, UTF-8 hat kein BOM. Diese Antwort ist falsch. Siehe den Unicode-Standard.

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