web-dev-qa-db-ja.com

BOMなしのUTF-8とUTF-8の違いは何ですか?

_ bom _ がないUTF-8とUTF-8の違いは何ですか?どちらが良いですか?

720
simple

UTF-8 BOMは、テキストストリームの先頭にある一連のバイト(EF BB BF)です。これにより、読者はより確実にファイルをUTF-8でエンコードされていると推測できます。

通常、BOMはエンコーディングのエンディアンを示すために使用されますが、エンディアンはUTF-8とは無関係であるため、BOMは不要です。

Unicode標準 によると、UTF-8ファイルのBOMはお勧めできません

2.6符号化方式

... BOMの使用はUTF-8に必須でも推奨されてもいませんが、BOMを使用する他のエンコード形式からUTF-8データが変換される場合、またはBOMがUTF-8署名として使用される場合に発生する可能性があります。 。詳細については、 セクション16.8、スペシャル の「Byte Order Mark」サブセクションを参照してください。

683
Martin Cote

他の優れた答えはすでに次のように答えています。

  • UTF-8とBOMベースのUTF-8の間に公式の違いはありません。
  • BOMされたUTF-8文字列は次の3バイトから始まります。 EF BB BF
  • これらのバイトが存在する場合は、ファイル/ストリームから文字列を抽出するときにそれらを無視する必要があります。

しかし、これに関する追加情報として、UTF-8のBOMは、文字列がUTF-8でエンコードされている場合に「匂いを付ける」ための優れた方法です。

たとえば、データ[EF BB BF 41 42 43]は次のいずれかです。

そのため、最初のバイトを見てファイルの内容のエンコーディングを認識するのはクールですが、上の例で示すように、これに頼るべきではありません。

エンコーディングは、神聖ではなく、知られているべきです。

208
paercebal

BOMをUTF-8でエンコードされたファイルに入れることには、少なくとも3つの問題があります。

  1. テキストを含まないファイルは、常にBOMが含まれているため、空にはなりません。
  2. UTF-8のASCIIサブセット内にあるテキストを含むファイルは、それ自体ASCIIではなくなります。BOMはASCIIではないためです。ユーザーがそのような従来のツールを置き換えることは不可能です。
  3. 各ファイルの先頭にBOMがあるため、複数のファイルを連結することはできません。

そして、他の人が言ったように、何かがUTF-8であることを検出するためにBOMを持っていることは十分でも必要でもありません:

  • BOMを構成する正確なシーケンスから任意のバイトシーケンスが始まる可能性があるため、これでは不十分です。
  • UTF-8であるかのようにバイトを読み取ることができるため、これは必要ありません。それが成功するなら、それは、定義により、有効なUTF-8です。
114
J P

これは多くの良い答えがある古い質問ですが、1つ追加する必要があります。

すべての答えは非常に一般的です。追加したいのは、実際の問題を実際に引き起こすBOMの使用例ですが、多くの人はそれについて知りません。

BOMはスクリプトを壊します

シェルスクリプト、Perlスクリプト、Pythonスクリプト、Rubyスクリプト、Node.jsスクリプト、またはインタープリターで実行する必要があるその他の実行可能ファイル-すべては シェバンで始まりますline これは、次のいずれかのように見えます。

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

このようなスクリプトを呼び出すときに、どのインタープリターを実行する必要があるかをシステムに伝えます。スクリプトがUTF-8でエンコードされている場合、最初にBOMを含めるように誘惑される可能性があります。しかし、実際には「#!」文字は単なる文字ではありません。実際、これらは マジックナンバー で、たまたま2つのASCII文字で構成されています。これらの文字の前に何か(BOMなど)を置くと、ファイルは異なるマジックナンバーを持っているように見え、問題につながる可能性があります。

ウィキペディアを参照してください 記事:Shebang、セクション:Magic number

Shebang文字は、UTF-8を含む拡張ASCIIエンコーディングの同じ2バイトで表されます。UTF-8は、現在のUnixライクシステムのスクリプトやその他のテキストファイルに一般的に使用されます。ただし、UTF-8ファイルはオプションのバイトオーダーマーク(BOM)で始まる場合があります。 「exec」関数がバイト0x23および0x21を明確に検出した場合、シバンがスクリプトインタープリターの実行を妨げる前にBOM(0xEF 0xBB 0xBF)が存在します。一部の当局は、POSIX(Unixライク)スクリプトでバイトオーダーマークを使用しないことを推奨しています[14]。この理由と、より広範な相互運用性と哲学的懸念のためです。さらに、エンコーディングにはエンディアンの問題がないため、UTF-8ではバイトオーダーマークは必要ありません。 UTF-8としてエンコードを識別するためだけに役立ちます。 [強調を追加]

JSONではBOMは違法です

RFC 7159、セクション8.1 を参照してください:

実装は、JSONテキストの先頭にバイトオーダーマークを追加してはなりません。

BOMはJSONで冗長です

JSONではillegalであるだけでなく、not needto JSONストリームで使用される文字エンコードとエンディアンの両方を明確に決定するより信頼性の高い方法があるため、文字エンコードを決定します(詳細については this answer を参照)。

BOMはJSONパーサーを壊します

JSONでillegal不要であるだけでなく、実際にはRFC 4627 で提示された方法を使用してエンコーディングを決定するすべてのソフトウェアを破壊します:

JSONのエンコードとエンディアンを決定し、NULバイトの最初の4バイトを調べます。

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

ここで、ファイルがBOMで始まる場合、次のようになります。

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

ご了承ください:

  1. UTF-32BEは3つのNULで始まっていないため、認識されません
  2. UTF-32LE最初のバイトの後に3つのNULが続かないため、認識されません
  3. UTF-16BEの最初の4バイトにはNULが1つしかないため、認識されません
  4. UTF-16LEの最初の4バイトにはNULが1つしかないため、認識されません

実装に応じて、これらはすべてUTF-8として誤って解釈され、無効なUTF-8として誤って解釈または拒否されるか、まったく認識されない場合があります。

さらに、推奨されるように実装が有効なJSONをテストする場合、実際にはUTF-8としてエンコードされている入力も拒否します。なぜなら、それはASCII文字<128で始まるため、 RFC。

その他のデータ形式

JSONのBOMは不要であり、違法であり、RFCに従って正しく動作するソフトウェアを破壊します。それを使用しないのは簡単なことですが、BOM、コメント、異なる引用ルール、または異なるデータ型を使用してJSONを破ることを常に主張する人々がいます。もちろん、必要に応じて誰でもBOMなどを自由に使用できます。JSONとは呼ばないでください。

JSON以外のデータ形式については、実際の外観を見てください。エンコーディングがUTF- *のみで、最初の文字が128未満のASCII文字でなければならない場合、エンコーディングとデータのエンディアンの両方を決定するために必要なすべての情報が既にあります。オプション機能としてBOMを追加しても、より複雑でエラーが発生しやすくなります。

BOMの他の用途

JSONまたはスクリプト以外での使用に関しては、ここで既に非常に良い答えがあると思います。これは実際の問題を引き起こすBOM文字の例であるため、スクリプトとシリアル化に関する具体的な詳細情報を追加したかったのです。

69
rsp

BOMなしのUTF-8とUTF-8の違いは何ですか?

短い答え:UTF-8では、BOMはファイルの先頭にあるバイトEF BB BFとしてエンコードされます。

長い答え:

もともと、 Unicode はUTF-16/UCS-2でエンコードされることが予想されていました。 BOMはこのエンコード形式用に設計されています。 2バイトのコード単位がある場合は、それら2バイトの順序を示す必要があります。これを行うための一般的な規則は、データの先頭に文字U + FEFFを「バイト順序マーク」として含めることです。 U + FFFEという文字は永久に割り当てられていないので、その存在を使用して間違ったバイト順を検出できます。

UTF-8はプラットフォームのエンディアンに関係なく同じバイトオーダーを持つので、バイトオーダーマークは必要ありません。ただし、UTF-16からUTF-8に変換されたデータで(バイトシーケンスEF BB FFとして)、またはデータがUTF-8であることを示す "署名"として発生する可能性があります。

どちらが良いですか?

なし。 Martin Coteが回答したように、Unicode規格では推奨されていません。 BOM非対応ソフトウェアで問題が発生します。

ファイルがUTF-8であるかどうかを検出するより良い方法は、妥当性検査を実行することです。 UTF-8はどのバイトシーケンスが有効であるかについて厳密な規則を持っているので、誤検知の可能性は無視できます。バイトシーケンスがUTF-8のように見える場合は、おそらくそうです。

48
dan04

BOM付きのUTF-8がよりよく識別されます。私はこの結論に困難な方法で到達しました。結果の1つがUnicode文字を含む CSV ファイルであるプロジェクトに取り組んでいます。

CSVファイルが部品表なしで保存されている場合、ExcelはそれがANSIであると見なして、意味のないことを示します。先頭に「EF BB BF」を追加すると(たとえば、メモ帳をUTF-8で、またはメモ帳++をUTF-8でBOMを使用して再保存すると)、Excelで問題なく開きます。

Unicodeテキストファイルの先頭にBOM文字を追加することを推奨します。「UTF-8、ISO 10646の変換フォーマット」、2003年11月、 http://tools.ietf.org/html/rfc3629 この最後の情報は、 http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html )にあります。

29
Helen Craigman

BOMは、どこかで、どこかでブームになる傾向があります(意図されていない(sic))。そしてブームしたとき(例えば、ブラウザ、エディタなどによって認識されない)、それはドキュメントの始めに変な文字として現れます(例えば、HTMLファイル、 _ json __ rss _ など)と、Twitterでのオバマ氏の講演中に経験した 最近のエンコードの問題のような厄介な問題を引き起こします

デバッグが難しい場所でテストが行​​われたりテストが無視されたりすると非常に厄介です。それで、あなたがそれを使わなければならないのでなければ、それを避けることが最善です。

17
Halil Özgür

質問: BOMなしのUTF-8とUTF-8の違いは何ですか?どちらが良いですか?

これは バイトオーダーマーク(BOM)についてのWikipediaの記事からの抜粋です 私はこの質問に対する確かな答えを提供すると信じています。

BOMとUTF-8の意味について:

Unicode規格では、 _ bom _ in UTF-8 が許可されていますが、その使用は必須でも推奨もされていません。バイト順はUTF-8では意味がないため、UTF-8での唯一の用途はテキストストリームがUTF-8でエンコードされていることを開始時に知らせることです。

NOT BOMを使用した引数:

BOMを使用しない主な動機は、Unicode対応ではないソフトウェアとの後方互換性です。BOMを使用しない別の動機は、「デフォルト」のエンコーディングとしてUTF-8を推奨することです。

引数 FOR BOMを使用して:

BOMを使用するための引数は、BOMを使用しない場合、ファイルがどの文字エンコードを使用しているかを判断するためにヒューリスティック分析が必要であることです。歴史的にそのような分析は、さまざまな8ビットエンコーディングを区別するために、複雑で、エラーを起こしやすく、そして時には遅くなります。 Mozilla Universal Charset DetectorやInternational Components for Unicodeなど、タスクを容易にするための多数のライブラリが用意されています。

プログラマーは、誤ってUTF-8の検出も同じように難しいと仮定します(大多数のバイトシーケンスが無効なUTF-8であるためではありません。これらのライブラリーが区別できるようにしようとしています)。したがって、すべてのUnicode対応プログラムがそのような分析を実行し、代わりにBOMに依存するわけではありません。

特に、 Microsoft のコンパイラとインタプリタ、およびメモ帳などのMicrosoft Windows上の多くのソフトウェアは、ASCII文字のみが含まれていないか、またはBOM、およびテキストをUTF-8として保存するときにBOMを先頭に追加します。 Microsoft Wordドキュメントがプレーンテキストファイルとしてダウンロードされると、GoogleドキュメントはBOMを追加します。

どちらが良いか、 WITH または なし BOM:

_ ietf _ は、プロトコルが(a)常にUTF-8を使用するか、(b)使用されているエンコーディングを示すその他の方法がある場合、U + FEFFの使用を禁止すべきである。サイン。"

私の結論:

ソフトウェアアプリケーションとの互換性が絶対に必要な場合は、BOMonlyを使用してください。

また、参照されているウィキペディアの記事では、UTF-8を正しく検出するために多くのMicrosoftアプリケーションがBOMに依存していることが示されていますが、これはall Microsoftアプリケーションには当てはまりません。例えば、 @ barlop で指摘されているように、WindowsのコマンドプロンプトをUTF-8で使用する場合typemoreなどのコマンドは、BOMが存在することを想定していません。 BOM isが存在する場合、他のアプリケーションの場合と同様に問題になる可能性があります。


chcp コマンドはコードページ 65001 でUTF-8(without _ BOM)をサポートします。

16
DavidRR

一部のファイルでは必須ではありません WindowsでもBOMがあることに注意してください。例は、SQL*plusまたはVBScriptファイルです。そのようなファイルにBOMが含まれている場合、それらを実行しようとするとエラーが発生します。

7

BOMのウィキペディアのページの一番下に引用: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2

「BOMの使用はUTF-8では必須でも推奨されてもいませんが、BOMを使用する他のエンコード形式からUTF-8データが変換される場合、またはBOMがUTF-8署名として使用される場合に発生する可能性があります

7
pib

BOM付きUTF-8は、ファイルに実際に非ASCII文字が含まれている場合にのみ役立ちます。それが含まれていて何もない場合、そうでなければ普通のASCIIとしてファイルを解釈していたであろう古いアプリケーションを壊すでしょう。これらのアプリケーションはASCII以外の文字に遭遇すると確実に失敗するので、私の考えではBOMはファイルがプレーンなASCIIとして解釈されることができるときにのみ追加されるべきです。

編集:BOMをまったく持っていないほうがいいということを明確にして、古いゴミがうまくいかない場合はそれを追加します。そして、その古いアプリケーションを置き換えるのは不可能です。

UTF8用のBOMを期待してはいけません。

7
James Wakefield

UTF-8でエンコードされた情報を表示したい場合、問題に直面しないかもしれません。たとえばHTMLドキュメントをUTF-8として宣言すると、ドキュメントの本文に含まれているものがすべてブラウザに表示されます。

しかし、WindowsでもLinuxでも、テキスト、 _ csv _ 、XMLファイルがある場合はそうではありません。

たとえば、WindowsまたはLinuxのテキストファイルは、考えられる最も簡単なものの1つで、(通常)UTF-8ではありません。

XMLとして保存し、それをUTF-8として宣言します。

<?xml version="1.0" encoding="UTF-8"?>

UTF-8として宣言されていても、正しく表示されません(読み取られません)。

私はフランス語の文字を含む一連のデータを持っていました。それはシンジケーションのためにXMLとして保存する必要がありました。最初からUTF-8ファイルを作成する(IDEおよび "Create New File"のオプションを変更する)か、ファイルの先頭にBOMを追加しないでください。

$file="\xEF\xBB\xBF".$string;

フランス語の文字をXMLファイルに保存できませんでした。

6
Florin Sima

BOMなしのUTF-8にはBOMはありません。ファイルのコンシューマがファイルがUTF-8でエンコードされているかどうかを知る必要がある場合(または知ることでメリットがある場合)を除きます。か否か。

BOMは通常、エンコーディングのエンディアンを判断するのに役立ちますが、ほとんどのユースケースでは必要ありません。

また、BOMは、それを知らない、または気にしていない消費者にとっては不要なノイズ/痛みとなる可能性があり、ユーザーの混乱を招く可能性があります。

6
Romain

これを別の視点から見ます。 UTF-8とBOMはファイルに関する詳細情報を提供するため、より良いと思います。問題が発生した場合にのみ、BOMなしでUTF-8を使用します。

私は長い間私のページで複数の言語を使用しています( キリル語 )と、ファイルがBOMなしで保存され、エディターで編集するためにそれらを再度開きます( cherouvim また注意)、一部の文字が破損しています。

Windowsのクラシック メモ帳 は、UTF-8エンコードで新しく作成されたファイルを保存しようとすると、BOMでファイルを自動的に保存することに注意してください。

個人的にサーバー側スクリプトファイル(.asp、.ini、.aspx)をBOMおよび。htmlファイルで保存しますBOMなし

6
user1358065

実際的な違いの1つは、Mac OS X用のシェルスクリプトを作成し、それをプレーンなUTF-8として保存すると、次のような応答が得られることです。

#!/bin/bash: No such file or directory

使用したいシェルを指定しているShebang行に応答して、

#!/bin/bash

あなたがUTF-8として保存するならば、BOM( BBEdit で言う)はすべてうまくいくでしょう。

6
David

この質問にはすでに百万もの答えがあり、それらの多くは非常に優れていますが、BOMを使用する必要がある場合と使用しない場合を明確にしたいと思いました。

前述のように、文字列がUTF-8であるかどうかを判断する際にUTF BOM(Byte Order Mark)を使用することは賢明な推測です。利用可能な適切なメタデータ(charset="utf-8"など)がある場合は、使用しているものが既にわかっていますが、それ以外の場合はテストしていくつかの前提条件を立てる必要があります。これは、文字列が由来するファイルが16進バイトコードEF BB BFで始まるかどうかを確認することを含みます。

UTF-8 BOMに対応するバイトコードが見つかった場合、その確率はUTF-8であると想定するのに十分なほど高く、そこから進むことができます。しかし、これを推測させられたとき、何かが文字化けしてしまった場合に備えて、読み込み中の追加のエラーチェックはまだ良い考えです。入力 がソースに基づいて UTF-8であるべきではない場合にのみ、BOMがUTF-8(つまりラテン1またはANSI)ではないと見なす必要があります。ただし、BOMがない場合は、エンコーディングに対して検証することで、それがUTF-8であるべきかどうかを簡単に判断できます。

BOMが推奨されないのはなぜですか?

  1. Unicodeに対応していないソフトウェアや準拠していないソフトウェアでは、ラテン1またはANSIと見なされ、文字列からBOMが削除されないため、明らかに問題が発生する可能性があります。
  2. 実際には必要ありません(コンテンツが準拠しているかどうかを確認し、準拠しているエンコーディングが見つからない場合は常にフォールバックとしてUTF-8を使用します)。

の場合、BOMでエンコードしますか?

それ以外の方法(charsetタグまたはファイルシステムメタを介して)でメタデータを記録できず、プログラムがBOMのように使用されている場合は、BOMでエンコードする必要があります。これは、BOMなしのものが一般的にレガシーコードページを使用していると想定されているWindowsで特に当てはまります。 BOMはOfficeのようなプログラムに、はい、このファイルのテキストはUnicodeです。これが使われるエンコーディングです。

それになると、私が今までに問題を抱えている唯一のファイルはCSVです。プログラムに応じて、BOMを持っている必要があります。たとえば、WindowsでExcel 2007+を使用している場合、スムーズに開きたい場合やデータのインポートに頼る必要がない場合は、BOMでエンコードする必要があります。

6
jpc-ae

Unicode バイトオーダーマーク(BOM)FAQ は簡潔な答えを提供します。

Q:BOMにどう対処すればいいですか?

A:従うべきいくつかのガイドラインがあります。

  1. 特定のプロトコル(例えば、.txtファイルに関するマイクロソフトの慣例)は、ファイルなどの特定のUnicodeデータストリームでBOMの使用を要求するかもしれない。そのようなプロトコルに準拠する必要がある場合は、BOMを使用してください。

  2. 一部のプロトコルでは、タグなしのテキストの場合にオプションのBOMが許可されています。そのような場合、

    • テキストデータストリームがプレーンテキストであることが知られているが未知の符号化である場合、BOMを署名として使用することができます。 BOMがない場合、エンコードは何でも構いません。

    • テキストデータストリームがプレーンなUnicodeテキストであることがわかっている場合(ただし、どのエンディアンではないか)、BOMを署名として使用できます。 BOMがない場合、テキストはビッグエンディアンとして解釈されるべきです。

  3. バイト指向プロトコルの中には、ファイルの先頭にASCII文字を必要とするものがあります。これらのプロトコルでUTF-8が使用されている場合、エンコード形式の署名としてBOMを使用することは避けてください。

  4. データストリームの正確なタイプがわかっている場合(例えば、UnicodeビッグエンディアンまたはUnicodeリトルエンディアン)、BOMは使用しないでください。特に、データストリームがUTF-16BE、UTF-16LE、UTF-32BE、またはUTF-32LEであると宣言されている場合は常に、BOMを使用してはいけません。

4

前述のように、BOM付きのUTF-8は、BOM非対応(または互換)ソフトウェアで問題を引き起こす可能性があります。クライアントとして _ wysiwyg _ プログラムが必要なので、私はかつてUTF-8 + BOMとしてエンコードされたHTMLファイルをMozillaベースの KompoZer で編集しました。

保存するとレイアウトは必ず破壊されます。これを回避するのに時間がかかりました。これらのファイルはFirefoxではうまく機能しましたが、Internet ExplorerでCSSの風変わりなレイアウトが破壊されることを示しました。無駄に何時間もリンクされたCSSファイルをいじるの後、私はInternet ExplorerがBOMfed HTMLファイルを好きではないことを発見しました。もう二度と。

また、私はちょうどこれをウィキペディアで見つけました:

Shebang文字は、UTF-8を含む拡張ASCIIエンコーディングで同じ2バイトで表されます。これは、現在のUnix系システムのスクリプトやその他のテキストファイルで一般的に使用されています。ただし、UTF-8ファイルはオプションのバイトオーダーマーク(BOM)で始めることができます。 "exec"関数がバイト0x23 0x21を明確に検出した場合、Shebangの前にBOM(0xEF 0xBB 0xBF)があるとスクリプトインタプリタは実行されません。一部の当局は、POSIX(Unix風)スクリプトでバイトオーダーマークを使用しないことを推奨しています。この理由のため、そしてより広い相互運用性と哲学的な懸念のためです。

4
Marek Möhling

http://en.wikipedia.org/wiki/Byte-order_mark から

バイトオーダーマーク(BOM)は、テキストファイルまたはストリームのエンディアン(バイトオーダー)を示すために使用されるUnicode文字です。そのコードポイントはU + FEFFです。 BOMの使用はオプションであり、使用されている場合はテキストストリームの先頭に表示されるべきです。バイトオーダーインジケータとしての特定の用途を超えて、BOM文字は、テキストがいくつかのUnicode表現のどれでエンコードされているのかも示します。

ファイルで常にBOMを使用すると、UTF-8とBOMをサポートするエディタで常にBOMが正しく開くようになります。

BOMがないという私の本当の問題は次のとおりです。次のものを含むファイルがあるとします。

abc

BOMがないと、これはほとんどのエディタでANSIとして開きます。そのため、このファイルの別のユーザーがそれを開き、次のようにいくつかのネイティブ文字を追加します。

abg-αβγ

おっと...今、ファイルはまだANSIにあり、「αβγ」は6バイトを占有しませんが、3を推測します。これはUTF-8ではないため、開発チェーンの後半で他の問題を引き起こします。

1
cherouvim

Visual Studio、SourceTree、およびBitbucketのプルリクエストに関する私の経験を次に示しますが、いくつかの問題が生じています。

そのため、署名付きのBOMには、プルリクエストを確認するときに各ファイルに赤いドット文字が含まれることがわかります(かなり面倒な場合があります)。

enter image description here

カーソルを合わせると、「ufeff」のような文字が表示されますが、sourcetreeにはこれらのタイプのバイトマークは表示されないため、プルリクエストで終了する可能性が高くなります。現在新しいファイルなので、bitbucketはこれを無視するか、別の方法で表示する必要があります。詳細はこちら:

赤いドットマーカーBitBucket diffビュー

0
Leo