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:
- UTF-32BE beginnt nicht mit drei NULs, daher wird es nicht erkannt
- UTF-32LE das erste Byte wird nicht von drei NULs gefolgt, daher wird es nicht erkannt
- UTF-16BE hat nur ein NUL in den ersten vier Bytes, daher wird es nicht erkannt
- 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.
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.
40 Stimmen
UTF-8 hat kein BOM. Wenn Sie einen U+FEFF-Codepunkt am Anfang einer UTF-8-Datei platzieren, muss besonders darauf geachtet werden. Dies ist nur eine dieser Microsoft-Namenslügen, wie die Bezeichnung einer Kodierung als "Unicode", obwohl es so etwas nicht gibt.
3 Stimmen
@Tronic Es gibt keine Methode, die immer funktioniert. Metadaten können falsch sein - sie können sagen, dass es sich um Latin1 handelt, aber tatsächlich UTF-8 oder umgekehrt. Daten können beschädigt sein oder falsch generiert, daher bedeutet nur weil es ungültiges UTF-8 ist, nicht, dass es nicht am besten als "UTF-8 mit ein wenig Korruption" interpretiert wird. Oft ist das, was es sein wird. BOM hilft dabei, zwischen "beschädigt/ungültiges UTF-8" und "beschädigt/ungültiges Latin1" zu unterscheiden.
0 Stimmen
Du möchtest dies normalerweise nicht, es sei denn, du hast einen spezifischen Bedarf. Es kann z.B. aus einem PHP-Fragment in dein HTML eingefügt werden. Das moderne Mainframe (und AIX) ist Little-Endian-UTF-8-fähig, auch wenn dies nicht "natürlich" ist. Solange du standardisierst, solltest du in Ordnung sein.
10 Stimmen
"Das moderne Mainframe (und AIX) ist little endian UTF-8-aware" UTF-8 hat keine Endians! Es gibt kein hin- und herschieben von Bytes, um Paare oder Gruppen von vier in die richtige "Reihenfolge" für ein bestimmtes System zu bringen! Um eine UTF-8-Bytesequenz zu erkennen, kann es nützlich sein, zu beachten, dass das erste Byte einer Mehrbyte-Sequenz "Codepoint" (die Bytes, die NICHT "einfache" ASCII-Bytes sind) das MS-Bit hat und alle ein bis drei weniger signifikante Bits gefolgt von einem Rücksetz-Bit. Die Gesamtzahl dieser gesetzten Bits ist um eins weniger als die Bytes, die in diesem Codepunkt enthalten sind, und sie werden ALLE das MSB setzen...
3 Stimmen
Es gibt keinen Unterschied, da utf-8 kein BOM hat. Utf-8 + BOM ist utf-8 + BOM, ein Nicht-Standard: verwendet von Microsoft und möglicherweise einigen anderen.
0 Stimmen
Für den Fall, dass dies jemand anderem hilft, habe ich festgestellt, dass (für Websites zumindest) auf Windows-Servern in IIS immer Dateien als UTF-8 mit einem BOM speichern sollten (und der reguläre Notepad macht dies, wenn Sie es im Dropdown-Menü Encoding im "Speichern unter" Dialog auswählen). Auf Unix-Servern speichere ich meine Dateien jedoch immer als UTF-8 ohne BOM (weil ich Kodierungsprobleme hatte, als mein Apache-Server meine PHP-Dateien lesen würde, wenn sie das BOM hatten). Notepad++ hat ein tolles "Encoding" Menü, um von einem zum anderen zu konvertieren.
0 Stimmen
Beim Lesen dieser Diskussion über den (angeblich) nützlichen Zusatz eines BOM frage ich mich: Da die meisten anderen Zeichencodierungen keine oder (angeblich) keine Codierungsidentifizierung benötigen, warum UTF dies braucht? Warum muss (müssen) die einzige(n) Codierungen, die geändert werden müssen, UTF sein? Warum kein BOM (oder Äquivalent zur Erkennung der Codierung) für Windows-1252 oder DOS-852 oder ISO 8859-1? Das ist eine sehr unfair Anforderung. Eine, die nur von Microsoft durchgesetzt werden soll. :-(
4 Stimmen
@arrow "Byte-Reihenfolge" bezieht sich darauf, wenn Sie zwei oder mehr Bytes haben, die ein einzelnes Zeichen darstellen, und Sie wissen müssen, in welcher Reihenfolge sie angeordnet sind, um sie korrekt lesen zu können. Windows-1252, ISO-8859-1 usw. sind alles Ein-Byte-Codierungen, es gibt nur ein Byte pro Zeichen, daher gibt es keinen Bedarf für ein Byte-Reihenfolgen-Kennzeichen, um zu sagen, wie man sie lesen soll. Sie sind nicht dazu gedacht, die verwendete Codierung zu erkennen; sie werden dafür verwendet, weil es ansonsten keine automatische Möglichkeit gibt, dies überhaupt festzustellen. Aber sie sind nicht zuverlässig dafür. BOMs bei Multibyte-Codierungen sind keine Microsoft-Sache, nur UTF8+BOM ist es.
1 Stimmen
Fact 1: UTF-8 ist eine byte-orientierte Codierung, die in Netzwerkreihenfolge übertragen wird, hat keine "Byte-Reihenfolge", benötigt keine "Byte-Reihenfolge". Fact 2: Die Verwendung von UCS-2 durch Windows, das ziemlich ähnlich zu UTF-16 ist, ist eine Mehrbyte-Codierung, für die Microsoft keinen BOM spezifiziert. Hol dir deine Fakten richtig @TessellatingHeckler.
1 Stimmen
@Arrow "Meine Fakten richtig haben"? Welche Fakten habe ich falsch verstanden? Deine Fakten widersprechen nichts von dem, was ich gesagt habe.
2 Stimmen
Du bist es, der das Konzept der "Byte-Reihenfolge" einführt, nicht ich (mein ursprünglicher Kommentar befasst sich nicht damit). Aber UTF-8 benötigt keine Byte-Reihenfolge, Erkennung oder Beschreibung. Es wird durch eine Sequenz von Bytes gebildet. Daher gibt es keinen Bedarf für ein Byte-Reihenfolgen-Mark in UTF-8. ... Zur Identifizierung: Da UTF-8 die zuverlässigste Codierung zur korrekten Erkennung ist (wenn UNICODE-Codepunkte über 128 verwendet werden), benötigt sie kein BOM. ... Nochmal: Tatsache 1: UTF-8 benötigt keine "Byte-Reihenfolge". Tatsache 2: Microsoft verwendet eine (angeblich) 2-Byte-Codierung ohne BOM, warum wird ein BOM in anderen Codierungen benötigt? @TessellatingHeckler
1 Stimmen
Utf-8 ist ein Byte-Stream, daher hat es wirklich keine Byte-Reihenfolge, aber in diesem Fall dient das 3-Byte-BOM sowieso als Signatur. Die Software sollte wissen, ob die Codierung ANSI oder utf-8 ist. Wenn utf-8-Inhalt als ANSI-Codierung behandelt wird, werden die resultierenden Zeichen falsch sein, weil Byte-Sequenzen als einzelne Zeichen behandelt werden, was falsch ist. Andererseits, wenn die Software ANSI-codierte Dateien als utf-8 behandelt, wird es Fehler geben aufgrund von fehlerhaften oder unvollständigen Sequenzen.
1 Stimmen
@Arrow Du argumentierst gegen Dinge, die ich nie gesagt habe. Codierungen, die ein BOM benötigen, benötigen es, um dir die Byte-Reihenfolge mitzuteilen. Codierungen, die kein BOM benötigen, brauchen es nicht, um dir die Byte-Reihenfolge mitzuteilen. UTF-8 hat im Spezifikation ein optionales BOM, das missbraucht werden kann, um die Verwendung von UTF-8 zu erkennen. Dies ändert nicht den Standard, weshalb es sich von klassischen Codepages unterscheidet. Es geht nicht darum, die Byte-Reihenfolge von UTF-8 zu erkennen, und das habe ich nie gesagt. DU hast die Byte-Reihenfolge eingeführt, als du gesagt hast "die (vermeintliche) Nützlichkeit, ein BOM hinzuzufügen". Wo verwendet Microsoft 2-Byte/kein BOM? DOTNet verwendet zum Beispiel 2-Byte+BOM.
0 Stimmen
Es gibt zumindest einen guten Punkt für bom: Apps wie Rar/Zip-Ersteller verschwenden keine Zeit damit, die gesamten Dateien vor dem Packen zu scannen, sodass das Packen der Dateien ohne bom höchstwahrscheinlich zu Datenverlust führen würde.
0 Stimmen
Einer führt zu unangenehmen Gesprächen auf Flughäfen.