BOM

BOM (文字コード)

[36] BOM (ボム) (BYTE ORDER MARK) は、 Unicode文字コードによる文字列の先頭に付与する特定のバイト列です。

[63] U+FEFF ZERO WIDTH NO-BREAK SPACE (ZWNBSP) は、 改行禁止を表す零幅文字です。

[37] BOMUnicode文字コードである UCS-2UCS-4UTF-8UTF-16UTF-32 などに存在します。それぞれの文字コードにおける U+FEFF ZERO WIDTH NO-BREAK SPACE 文字に対応するバイト列文字列の先頭に置くことで、 エンディアンやどの文字コードを使っているかを識別できます。

[38] BOM は、そのバイト列によって表される文字列の一部ではないので、 バイト列から文字列への変換で除去されるべきものです。本来の文字としての ZERO WIDTH NO-BREAK SPACE を使いたいことはほとんどありませんが、 先頭に U+FEFF を2つ並べると1つ目は BOM、2つ目は ZERO WIDTH NO-BREAK SPACE とみなされます。

[39] BOMバイト列の先頭でのみ使われます。途中では使うことができません。
[40] BOM は必須ではありません。

代替

[54] BOMUTF-16 の衰退と UTF-8 への統一により不要となり、 あまり使われなくなりました。

[55] ZWNBSPBOM との混同を避けるため、使われなくなりました。 元の用法ではかわりに WORD JOINER が使われています。

仕様書

意味

[73] BOM は、 Unicode文字列を表すバイト列の先頭で用いて、 文字コードUnicode であることを示し、 しかも具体的にどのバイト順符号化 (または UTF-8) であるか区別できるように示すものであります。 >>72

構文

[74] BOM は、 各文字コードにおいて、 U+FEFF を表すバイト列です。

[75] Unicode では次のバイト列とされています。 >>72

[81]プロトコルは必ずしもこのすべてを認めてはいません。 例えば WebUTF-8UTF-16 の3種類のみ対応しています。 復号

[95] 古い実装は、 0x00 0x00 0xFE 0xFF と 0xFF 0xFE 0x00 0x00 を U-7FFFFFFF まであった昔の UCS-4 と解釈することがあります。 同様に 0xEF 0xBB 0xBF を昔の UTF-8 と解釈することがあります。

[96] 一部の実装は、 0xFE 0xFF 0x00 0x00 を X-ISO-10646-UCS-4-3412、 0x00 0x00 0xFF 0xFE を X-ISO-10646-UCS-4-2143 と解釈するようです。

[97] 理屈上は GB 18030 でも BOM を使えるはずですが、 実例があるかは不明です。

[98] UTF-7 が何通りもあるのは、続きのバイト列と共に Base64 符号化した先頭部分だからです。

[82] U+FFFE非文字とされており、 情報交換される Unicode文字列には含まれないことになっています。 そこで先頭に現れるとすれば U+FEFF だと仮定して判定できます。

[83] 0xBB, 0xBF, 0xEF, 0xFE, 0xFF は、 ISO/IEC 8859-1, Windows-1252, MacRoman, Adobe Standard Encoding, EBCDIC といった既存の文字コードで使われることはあるものの、 この組み合わせでは出現する可能性が低いとされています。 >>72


[86] BOM が使われる場合、 当該Unicode文字列を表現するバイト列は、 当然、 BOM を表すバイト列の長さの分、長くなります。 変換するソフトウェアは、 変換結果を格納するバッファーの長さの決定に注意が必要となります。

[87] BOM を使う場合、 空文字列を表すバイト列の長さが 0 ではなくなります。 バイト列としての長さ判定をもって文字列の指定の有無を判定するようなプログラムは意図通りに動作しません。

[88] BOM を使った (または使われている可能性がある) Unicode文字列の連結は、 単純なバイト列の連結とは異なることに注意が必要です。

BOM と符号化ラベル

[53] Web (Encoding Standard) では、符号化ラベルBOM の両方が存在する場合、BOM が優先されることになっています。 復号

BOM の処理

[59] 現在では普通文字コードUTF-8 です。 UTF-8 で出力するソフトウェアは、 BOM生成するべきではありません。 今となっては BOM は使う意味がなく、 かえって混乱のもとになります。

[60] バイト列を解釈するソフトウェアは、 文字コード復号の規定に基づき、適宜 BOM を無視しなければなりません。 その場合先頭の 0xFEFFBOM 解釈しなければなりません >>72。 もはや BOM に意味がないとはいえ、 既に BOM がついたデータが大量に生成されていますし、 未だに BOM がついたデータを生成するソフトウェアが残っていますから、 すべてのソフトウェアは BOM のあるデータに対応しなければならないのです。

具体的には UTF-8 などの復号を参照

[61] BOMバイト列から文字列に変換する時点で除去するべき (should) です >>72文字列を操作するソフトウェアBOM に対応する必要はありませんし、 むしろ何もしてはいけません。 (プログラミング言語文字列型は、 文字列なので、 操作するプログラムBOM を意識しなくて構いません。)


[93] The Unicode Standard に示された BOMバイト列 (>>75) のうち、 BOCU-1UTF-7 のものは、 それ以後のバイト列の解釈に影響が出てしまうので、 すべて含めて一体として文字列に変換して、 その先頭の 0xFEFF を除去する必要があります。 >>72

[94] それ以外の文字コードBOMバイト列は、 バイト列として除去し、 それ以降のバイト列だけ文字列に変換することができます。 >>72

文字 ZWNBSP

[64] 文字として現れる U+FEFF の意味は、 WORD JOINER と同じです。 >>62 すなわち、 それと前後の文字との間で原則改行が禁止されることを示します。 WORD JOINER

[65] Unicode 3.2 までこの機能には ZWNBSP を使うことになっていましたが、 BOM としての方が使われるようになったため、 WORD JOINER が追加されたとされます。 >>62 故に Unicode 3.2 までとの互換性のためを除き、 U+FEFFZWNBSP として使用しないこととされています >>72文字の名前byte order mark でなく ZERO WIDTH NO-BREAK SPACE であるのは、 歴史的理由であるとされます >>72 (文字の名前の変更は認められていません)

[68] 理屈の上ではバイト列の先頭にあるのが BOM文字列の任意の位置に現れ得るのが ZWNBSP と明確に区別し得ますし、 BOM が認識されなかった場合でも目に見えない零幅文字なので害はない、 というのが当初これに2つの意味を持たせた設計思想だったのでしょう。 実際にはことはそううまく進まず、 0xFEFF の扱いには混乱がありました。 それで結局別の符号位置を用意することになったようです。 The Unicode Standard は、 BOM が入ったファイルを連結すると途中に 0xFEFF が入ってしまうが、 ZWNBSPBOM の2つの意味があるので 0xFEFF を無条件に除去できないことを、 設計の失敗として挙げています >>72

[66] 新しいテキストでは U+2060 WORD JOINER を使うことが強く推奨 (strongly preferred) >>62, >>72 (べき (should) >>72) されます。 >>62, >>72

[67] 実装は、 後方互換性のため、 U+FEFF にも対応し続けるべき (should) です。 >>62

[85] BOM が使われる場合に先頭の ZWNBSP を表すためには、 先頭に 0xFEFF が2つ現れることになります。 >>72


[84]UTF-16BE」, 「UTF-16LE」 のようにバイト順が明示されている場合や、 文字列を扱う APIデータベースなどでバイト順が既知である場合には、 0xFEFFBOM ではなく ZWNBSP と解釈します。 >>72

[69] DOCS によって ISO/IEC 10646 に切り替えられた直後の 0xFEFF がどう解釈されるべきかは不明です。 ISO/IEC 10646におけるエスケープシーケンス

文脈

[100] PDF 中の UTF-16BE 文字列の先頭には、 BOM を書きます。

関連

[70] ZWSP, NBSP とは挙動が違います。

[71] 爆発はしません。

歴史

ISO/IEC 10646 における BOM

[1] ISO/IEC10646 には「byte order mark」という言葉は出てきません (UnicodeStandard には出てきます)。 10646 は BOM のことを、「UCS を識別する『signature』」と呼んでいます。 ISO/IEC 10646-1:2000 附属書 H (参考) The use of “signatures” to identify UCS に説明があります。

This annex describes a convention for the identification of features of the UCS, by the use of "signatures" within data streams of coded characters. The convention makes use of the character ZERO WIDTH NO-BREAK SPACE, and is applied by a certain class of applications.

なんだそーです。使いたけりゃ使えば? 的で結構さめてます。 引用部の後の方の記述によると、

UCS-2 signatureFEFF
UCS-4 signature0000 FEFF
UTF-8 signatureEF BB BF
UTF-16 signatureFEFF

ってことですが、別に UCS-2/4, UTF-8/16 を区別できるのが 嬉しいのじゃなくて、その名の通りバイト順を区別できるのが嬉しいんです。

  • UCS-2/UTF-16BE: FEFF
  • UCS-2/UTF-16LE: FFFE
  • UCS-4/UTF-32BE: 0000 FEFF
  • UCS-4/UTF-32LE: FFFE 0000

このように、エンディアンが識別できるんです。素晴らしいでしょ? :-)

だから UTF-8 ではこんなの要らんのですが、一貫性かなんかのために、 つけようというのが当世風。対応してない応用からすると頭にゴミです。 おまけに、 UTF-8 の最大の特徴であった ASCII との互換性を ぶっ飛ばしてしまいます。

ZERO WIDTH NO-BREAK SPACE (ZWNBSP) が U+FEFF に置いてあって、 U+FFFE が「not a character」になってるのは偶然じゃありません。 BOM に使うためにわざわざこう配置したんです。

で、あとから BOM ありなし問題云々で U+FEFFZWNBSP 本来(?)の役目に使うことが出来ない状況になってしまった (ほんとか?) もんですから、 ZERO WIDTH NON-JOINER (だっけ?) とかを別に追加することになったとか。 (そして追加されたとか。) しょーもない話ですなあ。

BOM は必須ですか?

[3] 質問:

BOMって本来必須なものだと思っていたのですけど、そうでもないんですね (http://www.airemix.com/bbs/ No.148-13)

[2] はい。 >>1 にあるように、原則として必要ありません。

ただし、 UCS を使用する場面などによって、その場面で使用する規格などが BOM を使わなければならないと規定していることあります。 その場合はもちろん必須になります。

UTF-8 と UTF-8n

[4] 質問: UTF-8 の名前に UTF-8UTF-8n があるようなのですが、どう違うのですか。

[5] まずはっきりさせておかないといけないこととして、 UTF-8n という名前はあまり知られていません。ですから、 UTF-8UTF-8n にはっきり使い分けがあるのかというと、そうでもありません。

[6] UTF-8n という名前を提案しているのは、 UnicodeConsortium のそれなりに偉い人 (誰かは忘れた。) のようです。 しかも、その人の文章 (どこにあったか忘れた。 dW かなあ。) では、使い分けが当然であるかのように書いてあります。

しかし、 Unicode や ISO/IEC 10646 の規格票を見ても、そんなことは全然書いてありません。 つまり、両者を使い分ける提案はありますが、標準化団体や世間で受け入れられているものではありません。 また、受け入れられるけはいもありません。

[7] さて、回答ですが、使い分けを提案している人は、 UTF-8nBOM なしの UTF-8 に、 UTF-8BOM ありの UTF-8 に使おうと言っています。

[9] しかし実際には UTF-8 という名前は BOM なしに対して呼ばれることが多いです。 (最近は BOM ありに対して言うことも多くなってきたようです。 (とはいえ、統計は無いので感覚的に、です。))

[8] >>9 のような状況でどうして >>7 のような定義を提案しているのかですが、おそらく BOM ありを普及させたい意図があるのでしょう。

[10] なお、 IETF charset 名 (MIME (電子メイル) や HTTP で使われる。) では UTF-8 だけを定義していて、その内容は BOM はあっても無くてもいい、というものです。

  • [14] 2004-02-17 05:00:41 +00:00 naruse: 結構UTF-8Nって使う人は多いように思いますよ。UNIX系で最初の一行で処理を決めるとき(#!なんちゃら)、BOMがあるとエラーになってしまうため、UTF-8Nでないといけないのです。

[15] >>14 Windows のメモ帳の影響がどれくらいのものかはわかりませんが、 基本的には今も昔も BOM なしの UTF-8 がずっと多いと思います。

ここで問題にされているのは、そのような話ではなくて、 BOM なし/ありの UTF-8 をそれぞれどのような名前で呼ぶかですよね。

  • BOM があってもなくても、どちらも (またはどちらかわからない状態を) UTF-8 と呼ぶ人がいる。
  • BOM があったら UTF-8 と呼び、 BOM がなければ UTF-8N と呼ぶ人がいる。
  • BOM の問題を知らない人がいる。
  • この問題とは関係ないけど、 UTF-8 のことを Unicode と呼ぶ人もいる。

「UTF-8N」といえば BOM なしであることに疑問の余地はありませんが、 「UTF-8」といった時に一般には BOM のあり・なしを断定できないのです。

経験的には、「UTF-8」に対応しているソフトウェアの多くは BOM ありまたは BOM なしのいずれかしか扱えなくて、 BOM なしだけを扱える方がずっと多く、 たまに、 BOM ありで最初に実装したソフトウェアに後から「UTF-8N」 と称して BOM なしを追加することがあるくらいの様に思われます。なんとなく。

XML における BOM

[46] XML MIME実体は、 BOM のない UTF-8 を使うべきです >>45

[43] XML では、 UTF-16 では BOM は必須とされています >>42。 また、外部実体置換文U+FEFF で始まる場合で、 実体テキスト宣言が含まれない場合には、 UTF-8 でも BOM は必須とされています >>42

[44] XML処理器UTF-8UTF-16BOM への対応が義務付けられています >>42

[31] XML 関連の MIME型の規定は、 RFC 2781 UTF-16 から変換する場合には BOM を除去し、 UTF-16 に変換する場合には BOM を追加することを要求しています >>45, >>33, >>32。 ただし UTF-8 との変換の場合を除きます >>45。 また UTF-8 から UTF-16 以外へ変換するときも、 BOM を除去することを要求しています >>45

[34] RFC 2376 時代はなぜか SHOULD でしたが、 RFC 3023MUST に修正されています。

[35] ただし RFC 2781 UTF-16BE, UTF-16LE (BOM が禁止されている) では BOM を付けてはならず、 UTF-16 と変換するときは BOM をつけたりはずしたりしなければならないともされています >>45, >>32

[47] BOM と他の文字コード指定との関係については、 XMLにおける文字コードを参照してください。

メモ

Unicode

[16] QA/Utf8BomInteropReport - ESW Wiki http://esw.w3.org/topic/QA/Utf8BomInteropReport (名無しさん 2006-12-13 12:36:42 +00:00)

[17] I18N Tests: UTF-8 signature 1 http://www.w3.org/International/tests/sec-utf8-signature-1.html

[18] BOM は Bomb? | | プログラマ2.0日報 | あすなろBLOG ( 版) http://blog.pasonatech.co.jp/sugiura/8981.html

[19] >>18

まあ「BOM が必要」なコンテキストというのは単に

今が移行期だから

ということであるに過ぎません。とっととこういうものは要らなくなるようになってほしいですね。

UTF-16 よとっととなくなれということですね、わかります。

[20] MAMA: Basic document structure - Opera Developer Community ( 版) http://dev.opera.com/articles/view/mama-basic-document-structure/#boms

The 3 BOMs were found in a total of 17,649 URLs (0.50% of all URLs analyzed). The BOM found most often is utf-8.

BOMFrequency
utf-817,006
utf-16 (little-endian)647
utf-16 (big-endian)26

[21] PHP スクリプトは BOM 付き UTF-8 で書いてはいけない - れぶろぐ (2009-01-29) (revulo 著, 版) http://www.revulo.com/blog/20090129.html#p01

[22] (X)HTML5 Tracking ( 版) http://html5.org/tools/web-apps-tracker?from=3852&to=3853

[23] Bug 12897 – In some parsers, UTF-8 BOM trumps the HTTP charset attribute (Encoding sniffing algorithm) ( 版) https://www.w3.org/Bugs/Public/show_bug.cgi?id=12897

[24] Web Applications 1.0 r7360 Make a BOM override HTTP headers. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=7359&to=7360

[25] Charinfo — "" ( ( 版)) http://chars.suikawiki.org/char/FEFF

[26] Web Applications 1.0 r7782 Strip a leading BOM from scripts in workers, if any. Also, use more of the encoding spec. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=7781&to=7782

[27] Re: [Json] JSON: remove gap between Ecma-404 and IETF draft ( (Martin J. Dürst 著, 版)) http://lists.w3.org/Archives/Public/www-tag/2013Nov/0102.html

[28] Re: BOMs ( (Bjoern Hoehrmann 著, 版)) http://lists.w3.org/Archives/Public/www-tag/2013Nov/0119.html

[29] http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cscript%3E%0A%20%20var%20p%20%3D%20document.createElement%20(%27p%27)%3B%0A%20%20p.innerHTML%20%3D%20%27%5CuFEFFabcd%27%3B%0A%20%20w%20(p.textContent.length)%3B%0A%3C%2Fscript%3EFirefox でも Chrome でも5になります。つまり innerHTML の先頭に U+FEFF があっても無視されません。

[30] http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Ciframe%3E%3C%2Fiframe%3E%0A%3Cscript%3E%0A%20%20var%20doc%20%3D%20document.getElementsByTagName%20(%27iframe%27)%5B0%5D.contentDocument%3B%0A%20%20doc.open%20()%3B%0A%20%20doc.write%20(%27%5CuFEFFabcd%27)%3B%0A%20%20doc.close%20()%3B%0A%20%20w%20(doc.body.textContent.length)%3B%0A%3C%2Fscript%3EFirefox でも Chrome でも5になります。つまり document.open + document.write で新しい文書を作成しても先頭の U+FEFF は無視されません。

[48] RFC 5854 - The Metalink Download Description Format ( ( 版)) http://tools.ietf.org/html/rfc5854#section-4.2.13

[49] Let the Encoding standard deal with the BOM · whatwg/html@83ebb72 ( 版) https://github.com/whatwg/html/commit/83ebb728198801e2f1a32b80ec7d7a2e7dccc593

[50] Clarify that using the BOM before Content-Type is a violation of sorts · whatwg/encoding@0a29220 ( 版) https://github.com/whatwg/encoding/commit/0a29220bd70173964f2e29bf8288c57f7255180a

[51] () http://www.cipa.jp/std/documents/j/DC-008-2012_J.pdf#page=70

[52] >>51 ExifDeviceSettingDescription タグの値は BOM 付きの UCS-2 と定義されています。

[56] Describe the relationship between encodings and Unicode encoding schemes (hsivonen著, ) https://github.com/whatwg/encoding/commit/6f9a41f3d9dbc7ba6d88f65f7ef1c139fb08d4be

[57] Add an informative note about the relationship of encodings and Unicode encoding schemes by hsivonen · Pull Request #151 · whatwg/encoding () https://github.com/whatwg/encoding/pull/151

[58] Give clearer advice on hooks for standards (annevk著, ) https://github.com/whatwg/encoding/commit/b579018b406d7752f8b7a3aa9c2bc800519c6f1a