DOMStringUSVStringcharsetinputEncodingxmlEncodingdocument.charsetdocument.characterSetTextEncoderTextDecoder\uunicode-rangeTextDecoderTextDecoderTextDecoder (ignoreBOM)TextDecoderreplacementfatal)replacementreplacementreplacementview-source:replacement<script charset>
2. 文書replacementreplacementjavascript:replacementreplacementreplacementapplication/manifest+jsonreplacementpayment-method-manifestreplacementPushMessageDatareplacementdocument.cookiereplacementreasonreplacementTextDecoderreplacementtext/event-streamreplacementreplacement
(fatal)replacementdecodeURIComponentDecode()URIErrorreplacementapplication/x-www-form-urlencodedreplacementmultipart/form-datareplacementreplacementm3u8replacementdata: URL処理器replacement[69] encoding sniffing algorithm (charset sniffing) は、 バイト列からその符号化を推定するアルゴリズムです。
[64] 文書形式や API ごとに似て非なるものが各仕様書で分散して規定されています。
[80] HTML, XHR 文書応答 HTML,
XML, script (古典スクリプト), CSS,
テキスト文書, XHR テキスト応答などの各場面での文字コードの判定方法をまとめると、
次のようになります。
charset (certain)<script charset><link charset><?xml-stylesheet charset?>[94]
対象となるファイルの種別ではなく、どこで使われるかによって処理の方法が異なることに注意が必要です。
同じ HTML文書でも、 navigate で開かれるときと responseXML
で開かれるときとで文字コードの判定の方法が異なるのです。
[95]
ソース表示 (view-source:) について規定する仕様書はありませんが、
少なくても Firefox では通常の HTML文書の navigate
と異なる判定を行っています。 (平文文書の navigate と
HTML文書の view-source: の判定方法が同じか異なるかは不明です。)
[89] charset sniffing に使うデータの長さについては、 >>121 や資源ヘッダーを参照。
[10] 著者や利用者が明示的に文字符号化を指定する方法はいくつかあります。 どれがどの程度の重みで使われるかが少しずつ違います。
[99]
古典的な Webブラウザーは GUI に文字コード指定メニューを実装していました。
CUI ツールの多くはコマンドラインオプション等の方法で同様の機能を提供しています。
encoding sniffing algorithm とその実装は完全ではないので、
こうした機能は Web互換性のために必須です。
[82] HTML Standard の HTML構文解析器は a known definite encoding を指定可能であり、 XHR の文書応答が HTML の場合にこれが使われます。 文書応答は、 HTML構文解析器の標準の (navigate で使われる) encoding sniffing algorithm のかわりに、独自の簡略化されたアルゴリズムを使っています。
[144] Web Applications 1.0 r8073 Provide a hook for XHR and web components to incrementally decode with a known encoding ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8072&to=8073
BOM による判定[96]
BOM による判定は、それのみを行う復号操作 (BOM sniffing)
を始め、多くの操作が採用しています。
[74]
仕様上 BOM は他の指定よりも優先されることになっています。
これは Trident, WebKit, Chromium の挙動に合わせて変更されたものです。
>>70
[77]
ただその根拠として示されている >>71 ページについて、現在
Internet Archive に保存されているものは、確かに HTTPヘッダーに誤った
charset が指定されており、実態および <meta charset>
と矛盾していますが、 BOM は見当たりません >>75。
同じサイトの議論より少し前の状態 >>76 では HTTP charset がなく、
議論の頃には誤った HTTP charset があり、
その少し後には HTTP charset がないのですが、
どの状態も BOM のない UTF-8 です。
あるいは User-Agent: 等によって出し分けがなされていたのでしょうか。
BOM があると確認していると信じたいところですが、
他の誰も追試報告をしていないんですよね...[59]
HTML Standard は利用者の指示よりも BOM を最優先としていますが、
文字コード指定メニューは BOM の誤認を上書き出来るべきと思われます。
IE や Safari や Chrome の挙動に合わせた規定のようです >>68
が、十分に検討されずに仕様が追随しただけのようです。
charset[138] encoding sniffing algorithm は転送プロトコルの文字符号化を使います。 >>104
[139]
HTML Standard は抽象化して明言していませんが、
HTTP や MIME の Content-Type: ヘッダーの MIME型の
charset 引数の記載がこれに該当します。
[141]
ただし Webブラウザーの実装上は転送プロトコルや MIME型の個々の規定は尊重されず、
およそ一律に Encoding Standard の符号化ラベルとみなされているようです。
[131] 明示的な指定がないときに呼び出し元の文字符号化の情報、 すなわち環境符号化が使われることがあります。
[66] Firefox はフレーム内の文書について (他の指定がないとき) 親閲覧文脈の文字符号化を継承します。 これは親と子が同じ文字コードのとき有効な推定ですが、 意外な罠があって、フレーム文書は ASCII文字のみで構成されることが意外と多く、 そのためにフレーム内が文字化けする事例が散見されます。 Windows-1252 は継承しないという配慮が必要なのでしょう。
[143] Web Applications 1.0 r7544 More detail on the inheritance of encodings from parent browsing contexts. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=7543&to=7544
[132] 限定的な状況で、異なる起源で指定された文字符号化の情報が使われます。 他の起源への情報漏洩ですから、注意が必要です。
[105] HTML や平文文書の navigate のための判定の処理 (encoding sniffing algorithm) では、 頻度解析等の手法 (frequency analysis or other algorithms) を適用することが認められています。 >>104
[107]
HTML Standard は、ネットワークから取得した資源の符号化を自動判定しようとすることは、
一般に勧められない、なぜならば本質的に相互運用可能ではない発見的手法に拠ることになるからだ、としています。 >>104
仕様書が頻度解析等の手法を認めるだけで必須とはしていないのは、
これが理由ということなのでしょう。確かに、 HTTP charset
や <meta charset> の処理と違って頻度解析等の手法を標準化するのは困難で、
従ってあるデータがどう解釈されるかが実装依存にならざるを得ません。
[106] しかし、現実の Web には HTTP charset も
<meta charset> も指定されてない Webページが散見されるのであり、
頻度解析等の手法はWeb互換性のため事実上必須の処理です。
仕様書が何と言おうと、実装は頻度解析等の手法を適用する以外の選択肢を持ちません。
[110] 頻度解析等の手法について、 HTML Standard は UNIVCHARDET を non-normative reference として提示しています。 >>104 実装方法はこれに限定されていません。
[109] 頻度解析等の手法は、対象となるデータのバイト列の他に、 文書の番地その他のメタ情報を使うことができます。 >>104 実際に Webブラウザーの文字コードの判定の実装は URL やその TLD を判定条件の1つとして使っています。
[116]
頻度解析等の手法の選択肢について具体的な限定はありません。
バイトの出現頻度の他に、
符号構造、
ASCII文字状バイト列の出現状態、
HTMLタグ状バイト列の出現状態、
URL、
ロケール設定などを総合的に勘案できます。
[63]
-*- coding -*-
のような Web 以外の文字コードの指定の方法
[121]
頻度解析等の手法の対象範囲となる長さについては規定がありません。
<meta charset> は1024バイトが目安となっていますが head が大きい場合など 1024 バイトでは頻度解析等の手法にとって十分な長さでないことが多いです。
[93] 頻度解析等の手法によって UTF-8 を判定することについては、 技術的問題から離れた主義主張があるようで、いくらか混乱した状態になっています。
[100]
ほとんどのプラットフォームにおいてローカルファイルの文字コードはファイルシステム等から確定的な情報を得ることが不可能ですから、
file: URL から取得したファイルの処理では頻度解析等の手法の適用が必須となります。
ただ、仕様書は file: の挙動を定めておらず、各実装の処理にも差異があります。
[101] 一般論として、ファイルの全体が読める場合、それが UTF-8 かどうかは高い確度で判定できます。現代のテキストファイルの大部分が UTF-8 ですから、ローカルファイルの先頭の十分な大きさを取得し、 UTF-8 らしさが高ければ、これを UTF-8 と判定するのが良いと考えられます。 大きすぎるファイルや長さが確定していない (書き込み中ないし無限の長さのストリームを扱えるプラットフォームにおける) ファイルのときは、適当な長さで打ち切る必要があります。
[102] ローカルファイルは Unicode 以前の文字コードのファイルの可能性も高く、 頻度解析等の手法によって判定する必要があります。 Linux、 Mac OS X、 Cygwin 等では POSIXロケールの符号集合が使われている可能性があります (ただし現代ではこれも UTF-8 のことが多いです)。 Windows では ANSIコードページや OEMコードページが使われている可能性があります。 更に、 Webブラウザーや OS の言語設定に応じた当地の文字コードの可能性があります。
[103] 例えば日本語 (言語タグ ja, POSIXロケール ja_JP)
が設定されている環境では、 UTF-8 の他にシフトJISや日本語EUCや ISO-2022-JP
のファイルがある可能性が少なくないので、これらを優先的に判定するのが望ましいと考えられます。
[117]
8ビット符号系のフォント依存符号化を使った Webページの多くは、
Windows-1252 として処理されることを前提としたフォントを使っています。
[118] encoding sniffing algorithm は、そうしたHTML文書を他の文字コードではなく Windows-1252 と判定する必要があります。
[119]
<meta charset> として ISO-8859-1, Windows-1252,
x-user-defined が指定される場合には、 Windows-1252 として処理されるので、
特に問題となりません。
[120]
<meta charset> にその他の値 (当該フォント依存符号化を表す
Encoding Standard の符号化ラベルではない値など)
が指定された場合や、 <meta charset> 等が存在しない場合には、
頻度解析等の手法の対象となりますが、ここで Windows-1252
以外と判定してしまうと、文字化けになります。
[125]
すべてのフォント依存符号化をバイト出現頻度によって検知することは困難なので、
現実的な手法としては、 <meta charset> の prescan と同様の方法によって
<font face> を検出し、フォント名が既知のフォント依存符号化のフォントであるとき、
フォント依存符号化が使われているとみなしてバイト出現頻度による推定を無効化することになります。
ただし、 UTF-8 の検知はそれよりも優先させるべきです。
[133] 頻度解析等の手法が ASCII文字のみを検知したときの扱いは注意が必要です。
[134] 復号だけを目的とするなら Windows-1252 や UTF-8 と検知しても問題にはなりませんが、 環境符号化や文書の文字符号化という形で非ASCII文字の扱いに間接的に寄与することがあります。
[136] 例えば日本語の HTML文書がたまたま短くて非ASCII文字を含まないときは、 Windows-1252 と判定するより、シフトJISと判定した方が有益な可能性があります。 そのためには、 ASCII文字のみの入力に対し、頻度解析等の手法は結果を返さず、 後続のロケール依存の既定値を設定する手順に進ませるのが良いと考えられます。
[137] Web 以外の用途を想定した判定器はこうした状況を考慮していないことがあるので、 encoding sniffing algorithm の実装時には判定器の選択や設定に注意が必要となります。
[65]
文字コードの判定を助けるため、紛らわしい他の文字コードに出現しない文字を含める技法を使うことがあります。
[62] Editorial: further cleanup "abort these steps" (shreyateeza著, ) https://github.com/whatwg/html/commit/99e2cdfc484c2ff14cbf5c38b859f4d6da17e64c
[84] 1280556 – Encoding detection mismatch on http://www.idpf.org/epub/pgt/ () https://bugzilla.mozilla.org/show_bug.cgi?id=1280556
# [17:23] <hsivonen> SimonSapin: I can't recall why I implemented the late <meta> thing in the new parser
# [17:23] <hsivonen> SimonSapin: initially, I make the detectors see at most 1024 bytes so that they couldn't trigger a reload
# [17:23] <hsivonen> SimonSapin: but that broke Japanese Planet Debian
# [17:24] <hsivonen> SimonSapin: and people get really nervous if you break a Japanese site
[124] Let the Encoding standard deal with the BOM · whatwg/html@83ebb72 ( 版) https://github.com/whatwg/html/commit/83ebb728198801e2f1a32b80ec7d7a2e7dccc593
[129] >>124 の変更により、利用者の指示や XHR の指示などによる上書きよりも BOM が最優先されるようになりました。また、 BOM があると confidence が certain に設定されていたのがなくなったので、 BOM があっても他の指定が優先されたり、符号化の変更が実行されたりするようになりました (もっとも結局 BOM が最優先されるので、最終的な結果は変わりません)。
[45] UTF-8符号化ではない符号化操作は、 UTF-8 以外の文字コードの符号化器を呼び出すことがあるものです。
[43] Webプラットフォームにおいて文字列がバイト列に変換される操作は多いですが、 その大部分は UTF-8符号化を使っています。 ASCII文字のみで同型符号化を使う操作も多いです。
[3] 現在のWebブラウザーが対応していない文字コード規格も過去には各種いろいろ使われていました。
[4] 今でも、古くから残っているウェブサイトや Internet Archive でたまに見かけるのですが、残念ながら通常の Webブラウザーでは文字化けにしか見えません。
[97] 20世紀末から21世紀初頭に作られた膨大な人類の遺産が切り捨てられている現状は実に嘆かわしいものです。
[98] Internet Archive にしか残っていないようなものはさすがに仕方がないとしても、 まだ現役の普通のウェブサイトにあるページすら読めないものが出てきているのは、 本当に困ったものです。
[17]
Dan Connolly の過去ファイルアーカイブ (MarkUp.html,v
によるとかつて info.cern.ch にあった HTMLの仕様書には時点で
<H2>For developers</H2> <DL> <DT><A NAME="z40" HREF="http://www.ntt.jp/japan/note-on-JP/encoding.html">Japanese encoding</A> <DD> How Japanese characters have been encoded within HTML
と NTT ウェブサイトへの参照があったようです。
[19] このリンクがいつまで残っていたのかわかりません。
[20] JPドメインの再編で URL が変わってからもしばらくは参照先の頁は残っていたようで、 >>18 に時点の参照が、 >>14 に時点の複製があります。
[40] Sample Pages for Various Character Sets, , https://web.archive.org/web/20060512035632/http://vancouver-webpages.com/multilingual/
[41] Une indigestion de jeux de caractères, , https://web.archive.org/web/19970502020520/http://www.ics.uci.edu/pub/ietf/html/multilingual.html
[54] IE3.01 MojiBake, https://groups.google.com/g/fj.net.infosystems.www.browsers/c/wnawyNwhm_I/m/CD7Ej3R0UOMJ
おかしな実装の例としては、(私の場合、全て MS-Windows95 での話ですが、) Netscape Navigator の Version 2 が、そうなっていました。 x-sjis は解釈できるが、Shift_JIS では文字化けしました。 Version 3/4 では、Shift_JIS を正しく解釈します。 但し、Version 4.0 Preview Release 2 には、Navigator の Encoding と、 META タグで指定された charset とが一致していない場合に、 <H3>Transfer Interruped !</H3> (もう記憶があいまいですが、確かこうだった) というものを、その時受けていたページの中に埋め込んでしまいます。 埋め込んだまま、cache に記録してしまうので、reload しても消えません。 私のページの場合、それがちょうど、表 <TABLE> - </TABLE> の中に入ってしまって、 表の表示がメチャクチャになってしまいました。 Version 4.0 Preview Release 3 では、そういうバグはありません。 それから、MS-IE 3.0/3.01 では、 META タグで charset を指定すると、かえって文字化けしやすくなる様です。 MS-IE 3.02/4.0では試していません。 さらに、Win32 版 Lynx の先月のバージョンでは、 META タグで charset を指定すると、必ず文字化けします。 もっともこれは、私が Lynx の設定をちゃんとしていないからかもしれません。
[55] https://groups.google.com/g/fj.net.infosystems.www.browsers/c/wnawyNwhm_I/m/HURaRZwFLwYJ
Win32 Lynx の名誉のために自分でフォローしときます。 META指定無し <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-2022-jp"> では、文字化けしません。 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=x-sjis"> だと、文字化けします。 なお、LYNX.EXE の作成日時は、97/03/14 18.19 です。
[31] Charsets in Microsoft Internet Explorer 4, , https://www.w3.org/International/ms-charset.html
[21] Re: proposed registration of type 'text/html' for MIME, , https://lists.w3.org/Archives/Public/www-talk/1992NovDec/0035.html
[22] >>21 この時点で TimBL は HTML は7ビットデータにしたがっていた。
[28] Internationalized HTTP?, https://groups.google.com/g/comp.infosystems.www/c/htw5XLv4Hj0/m/wPr5IAol_EIJ
[23] What is standard for cyrllic HTML ? Hebrew ? Arabic ?, https://groups.google.com/g/comp.infosystems.www.providers/c/lBJKtyujAk4/m/yRxsWMDGpZUJ
[27] WWW and cyrillic, https://groups.google.com/g/relcom.tcpip/c/dUBIIAE-MnM/m/i_YJic8dqjUJ
[48] Official Google Blog: Unicode nearing 50% of the web, , https://googleblog.blogspot.com/2010/01/unicode-nearing-50-of-web.html
[8] >>7 JavaScript MIME型の文字コード処理 (実装された例があるかは疑わしい)
[30] 詳しい条件は不明ながら、 Chrome はメモリー不足だと文書中から読み込むファイル (CSS など) の文字コード判定に失敗して Windows-1252 として読み込んじゃう(ことがある)っぽいなあ。
[32] compact_enc_det/util/encodings/encodings.cc at master · google/compact_enc_det · GitHub, https://github.com/google/compact_enc_det/blob/master/util/encodings/encodings.cc
[33] Usage Statistics and Market Share of Character Encodings for Websites, June 2025, https://w3techs.com/technologies/overview/character_encoding
UTF-8 is used by 98.7% of all the websites whose character encoding we know.
となっている。
[35] >>34 の通り UTF-8 が今や圧倒的に多いのだろうが、古くから残る頁はこうした統計の対象になりにくいことが多いので漏れてしまう。 また、少ないデータは精度が落ちる。
[36] EUC-JP が 0.1%、 Shift JIS が 0.1% 未満となっていて EUC-JP の方が優勢になっているが、 にわかに信じがたい。 Shift JIS の頁を見ると、 まで 0.25% と 0.3% の間だったのがには0.05%と急激に落ちているが、その前後はほとんど横ばい。 こういう結果が出ているということは、どこか特定のサイトが UTF-8 に一括変更したか、 調査対象から外れたことが疑われる。
[38] >>36 WIndows-31J も同じ時期に 0.0008% から 0.0002% に減少しているのはなんか怪しい。
[37] また、割合が少ない文字コードを使っているドメインを見ると銀行なんかが入っていたりする。 割合が少ないからといって重要なサイト、よく見られるであろうサイトが入っていないということではない。 保守的で大規模なシステムを抱えているところが古い文字コードのままというのはよくあること。
[39] >>34 では ansi_x3.110-1983 なるものまで上位として挙げられている。
これは誤りと考えられるもの (
[49] Character Set Test Area, https://charsetplus.tripod.com/HTMLs/index.html
[50] 欧米偏重のWebブラウザー事業者による従来文字コード切り捨てについてはいろいろ語るべき点があるのでしょうが、 それがわかりやすく表れているのが越南語かもしれません。
20世紀に広く用いられていた越南語の文字コードを Encoding Standard はどれ1つとして収録していません。今の Webブラウザーでは20世紀のベトナムの Webサイトがまったく読めません。
そのかわりに Encoding Standard は Windows-1258 を規定しています。 Windows-1258 は Microsoft が越南向けに開発した文字コードですが、当時ほとんど使われておらず、 Web 上に (Internet Archive を探しても) Windows-1258 の Webサイトは皆無です。 なぜ Encoding Standard にあるかといえば、他の欧米等の Windows-125x シリーズとまとめて全 Webブラウザーが実装していたからです。 誰も現地の実態を調べていません。
[52] >>51 は Firefox の文字コードの判定の実装の作り直しがに行われたときのものですが、 越南語は Unicode と違って Windows-1258 だと分解が必要なので工夫してデータを作った!と報告してます。
でも今も当時も Windows-1258 のWebページなんてない、あったとしても天然記念物レベルなので、 そんな文字コードの判定に対応しても誰の役にも立たないのです。
そして当時の実際の文字コードはというと、 VN3, VISCII, VPS は現在の Unicode の一般的な用法と同じで分解されていない合成済文字。 VNI (Web で使われた ANSI 版) は2文字の組合せで表すことは Windows-1258 と似ていますが、組合せ方はまったく違います。 Windows-1258 専用のデータはこのどちらにも流用できません。
そんな基礎的事実を確認しないまま実装を進めているというのが現実なわけです。
[53] Description of settings in lynx configuration file, , https://lynx.invisible-island.net/lynx_help/body.html#CHARACTER_SET