[31] 文字コードを識別する名前の体系には色々なものがあります。
[24] 各種のプロトコルや文書形式、 プログラミング言語や文字コードの変換の実装などでそれぞれ文字コードの識別子の体系を定めています。
MIBenumcharset-editioncharset-extensionencoding=""Encode.pm の名前encodingID[25] 歴史的に見ればインターネットでは IANA charset の影響力がかなり強いものの、 それ単独で用いるほどカバー範囲と定義の厳密性はなく、 各種の実装はそれを取り込みつつ各分野の従来の慣習と統合する形を採っており、 似て非なる体系が大量に生じています。
[20] 数値符号を除けば、ASCII文字で構成されるものが多いです。
[21] 稀に非ASCII文字が使われるものもあります。 文字コードの指定がなされる場面で非ASCII文字は安全に使えないことが多いので、 矛盾した状況にも思えますが、稀とはいえ現に存在します。 とはいえ多くは仕様上認められていない利用方法です。
[22] ASCII文字の諸記号は、どれを使えるか制限されていることもありますが、 守られていない場合もあります。 どれが使われるかは慣習によるところが大きいですが、 一貫しないものや体系によって違うものも多く、 統一的な基準は無いと考えて構いません。 無視したり統一したりする実装もありますが、 それによって名前が衝突する場合もあります。
[23] 大文字と小文字は、区別しないことが多いです。 正規形が定義されていることもありますが、まず意味がないと考えて間違いありません。 実態としても様々な形で使われており、 文脈と個別の文字コード次第でどの書き方が多いという傾向は多少あれども、 強い慣習といえるものはありません。
[16] 似た構造の文字コードに統一的な名称を与えようとした試みもありますが、 他の色々な名前が混在する中で統一的な命名規則を徹底するのは難しいようです。
[17]
charset-edition や charset-extension
のように識別子を多次元化する試みもありましたが、成功していません。
[30] 多くの文字コードは正式な唯一の名前が無かったり、 機械的な識別子としての利用に適した名前では無かったり、 人間向けと機械向けで違う名前を用意していたり、 識別子の体系によって違う名前を与えられていたりします。
[7] また、識別子の体系の管理が破綻していて、 正式な定義と実際に使われるものと違いが生じていたり、 正式な定義がないまま事実上の標準となるものが使われていたりすることもままあります。
[8] 他の識別子の体系の識別子が移入されて使われることも多いのですが、 丸々同じものを採用せずにつまみ食い + 独自分、というパターンが非常に多いので、 利用者の正確な理解を妨げています。
[6] たまに識別子に含まれる些細な記号や空白の違いで「この文字コードをこれこれというのは誤りで、 これこれというのが正しい」と主張する人が出現しますが、 そのような主張は正しくないことが多いです。 「これこれの場面ではこれこれの名前が正しい」 のような限定的な条件でしか成立しないことを、勝手に拡大解釈するタイプです。
[10] より深刻な問題として、識別子が文字コード体系の細かなバリエーションのどれを指しているのか明らかでない場合や、 正式な定義と世間の実態が乖離している場合が多くあります。 識別子の体系が細かなバリエーションを区別しているのに、 実態としては混用されているような場合もあります。
[9] こうした問題は解決しないまま UTF-8 への移行が進み、表立ってトラブルにつながることが少なくなったのはいいことですが、 一方で問題の発生数が減って見えにくくなったり、 古いデータやプログラムの理解に問題があるのを修正されないままとなっていたり、 トラブル解決のための情報が減少していたりと、 狭く深い問題に変化しつつあります。
[12]
BOM 有無など出力時の動作オプションに当たるものが文字コード名に取り込まれていることがあります。
[11] 狭義の文字コードの体系の他に、改行文字の種別や Unicode正規化の適用などの動作オプションが文字コード名に取り込まれていることがあります。
[13] Base64 など内容転送符号化や符号化語 escape のような文書形式やプロトコルの構文、あるいはそれと狭義の文字コードとの組合せも 「文字コード」として名前が付与されていることがあります。
[28] 照合順序との組合せに名前が付与されていることがあります。
[14] 文字コードの自動判定も1つの「文字コード」として名前が与えられていることがあります。 判定法の違いにもそれぞれ名前が与えられていることがあります。
[26] 単独で用いられる文字コードの他、エスケープシーケンスで切り替えられる符号化文字集合やフォントの記述に用いられる符号化など、 狭義の文字コードの体系といえるものの中にも性質が異なるものが混在しており、 識別子の体系はそれらを区別したりしなかったりしています。
[18]
x-user-defined,
replacement,
x-transparent,
default prc japan raw-text,
no-conversion,
ASCII-8BIT,
undecided,
prefer-utf-8,
unknown-8bit
のように特殊な「文字コード」もあります。
[19] 特殊な「文字コード」は特定の場面で認識され、特定の場面では認識されないなど、 扱いが通常の文字コードと違うことがよくあります。
[32] 文字コードの識別子を付けてデータを送出する実装は、 選んだ文字コードの名前をそのまま書くのかどうか判断を迫られる場合があります。 文字コードの選択と連動することもあれば、独立している場合もあります。
[33] ある文字コードが別の文字コードの部分集合、という関係性が成立する組合せが多数あります。 ある文字コードと別の文字コードは全体としては互換性がないものの、 一部のビット組合せの割当は共通しているので、その範囲内ならどちらとしても解釈できる、 という組合せもいくつもあります。
[35] ISO/IEC 8859-1 と ISO/IEC 8859-15 の符号化文字集合のビット組合せの大部分は共通です。
[36] MIME は最小公倍数を選ぶように求めています (>>145)。 しかし具体的にどう選ぶべきかは決めておらず、実装に丸投げしています。
[37] MIME charset US-ASCII よりも IANA charset
ISO_646.basic:1983 の方が更に部分集合ですが、
可能ならこれを使うべきなのかどうか定かではありません。
[38] 実際上は US-ASCII とするべきと考えられますが、
明文規定上そう考えるべき理由は無さそうに思われます。
[39] 当時も今も、このような扱いづらい規定を厳密に適用している実装はさほど多くありません。
[145] 一般に MIME の生成ソフトウェアは、
charset に可能な限り「最小公倍数」
たる文字集合を使うべきです >>265
(charset最小化)。
[102] MIME では未知の text/* MIME型は
text/plain として扱うことになっています。
charset 引数がこの際どう扱われるかは不明です。
[2] MIME charset の最小化規則と、 HTTP CGI のような動的生成って本質的に相容れないもののような気がしませんかね。あるいは streaming 的なものとも。 chunked符号化の尾っぽ header を使えば何とかならなくもない気もするけど, クライアント側で届いたところからレンダリングが不能になって結局意味がない (サーバー側でデータ生成完了後に charset を判定して一気に送りつけるのと変わらない) し、よって steraming には使いようがないし。
[40] MIME の当該規定は、 ISO/IEC 8859 規格群が使われている欧米諸国でも英文は通じるようにというくらいのニュアンスで作られたものと思われます。
[41] その他に東アジアの各社の独自外字が追加された文字コードを使っていても、 標準の文字だけなら標準の文字コードを名乗るべきだとする仕様上の根拠としても使えるものです。
[42] ところが現実には欧米でも東アジアでも、市場で優位な外字を使った文字コードが標準の IANA charset を名乗るという現象が起こりました。
[43] 例えば ISO-8859-1 は windows-1252 の意味で使われ、
Shift_JIS は windows-31j の意味で使われています。
[44] 市場で普及した実装には文字コードの識別子を厳密に使い分けるという意識がなく、 市場で広まっている識別子で当該文字コードに近いものを選べば概ね正しく解釈してもらえる (自社製品なら完全に正しく解釈できるからなおよし) というくらいの気持ちだったのでしょう。
[46]
本来なら IETF がこうした傾向が見えた時点で何らかの技術的対応を行うべきだったのでしょうが、
IETF は完全無視して放置したため、混乱が続き、たまたま選んだ製品の違いによって他の製品の利用者を攻撃するような人も出てくるような始末でした。
[47] 文字コードの判定の処理では、判定結果を返すために何らかの既知の文字コードを選ぶ必要があります。
[48] 判定対象のバイト列によっては、該当する文字コードがいくつも存在することがあります。 (ここで問題とするのは、候補を絞り込めないときではなく、 バイト列がそれらの共通部分しか使っていないときです。)
[49] 判定器には3つの選択肢があります。
[53]
>>52 は、例えば HTMLにおける文字コードの判定の場合、結果は文書の文字符号化として参照可能になります。
document.charset でアクセス可能ですし、
フォームの提出があればその文字コードでフォームデータが送出されます。
[54] >>53 に対しては反論もあるでしょう。もしそのような処理にとって重要なら、 文字コードの指定が省略されているはずがありません。 それがなく判定器の推定に頼らざるを得ないという時点で、そうした処理が入っていないか、 あっても長らく機能しない状態で放置されているに違いありません。 従って、わざわざ苦労してどれかを選ぶ必要はありません。
[56]
見落とされがちで >>53 で意外と重要なのは、文字コードに依存したフォントの選択かもしれません。
明示的な言語情報が存在しない場合、文字コードによってフォントが変わって表示される場合があります。
[57]
同じような英文でも
ISO-8859-1 で欧文フォントで表示されるか、
Shift_JIS で和文フォントで表示されるかで意外と雰囲気がかわります。
[58] メールを読み進めると記事ごとに意味もなくフォントが変わる、 というのは読者にとってあまり快適ではない体験です。
[55]
>>52 を実装するとしたら、例えばロケール等による文字コード判定の補助のような手法が適用できそうです。
[29] GNU gettext - Bugs: bug #50357, xgettext doesn't recognise... [Savannah] (Copyright 2016 Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.著, ) https://savannah.gnu.org/bugs/?50357