小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


クラシックASPの内部文字コードについて調べてみた。

Active Server Pages(以下、クラシックASP)のスクリプトエンジンは、文字情報を内部でどのような文字コードとして扱っているのかを調べてみました。

結論から言いますと、文字コードセットはUCS-2。そして、エンコーディング方式にはUTF-16LEが使われています。

内部コードはUCS-2なのか?

以下は、UTF-8エンコードのASPページについて書かれた記事ですが、クライアントから送信されたデータは、IISが自動的にUCS-2に変換すると記載されています。

アプリケーションが Active Server Pages (ASP) を使用し、Internet InformationServer (IIS) と Microsoft Windows 2000 を使用する場合には、サーバ側の ASP スクリプトに、"Session.Codepage=65001" を追加します。これは、動的に生成された文字列 (Response.Write) をクライアントに送信する前に IIS が UCS-2 から UTF-8 に変換するようにします。

また、GET や POST でクライアントからサーバに送られた UTF-8 のデータも、UCS-2 に自動的に変換されます。
[SQL]INF: SQL Server に UTF-8 のデータを格納する

さらに、次のページでも自動的にUCS-2に変換されると記載されています。実際に僕が試した場合も同様で、クライアントから送信した英数字のバイト数は、1文字2バイトでした。

問題:
Webブラウザから送信されたUTF-8文字列をASPが受け取ったとします。Request.Form()メソッドで返される文字列の文字コードは何になるでしょうか。ただし、IISが稼動しているOSは、英語版のWindows 2000 Serverとします。

読者をじらしても意味がありませんので、解答をお教えします。答えは、WindowsのUnicodeであるUCS-2の文字列です。うれしいことにUTF-8からUCS-2への変換は、ASP上で自動的に行われます。
UTF-8対応Webアプリケーションの構築: 第1回(ASP)

上記のことから、僕は、今まで内部コードはUCS-2なのだと思い込んでいました。

内部コードはUTF-16なのか?

以下のMicrosoftのページには、ASP によってサポートされるスクリプト エンジンでは、内部でUTF-16を使用しているという記載があります。

Active Server Pages (ASP) と、ASP によってサポートされるスクリプト エンジンでは、内部的に Unicode が使用されます。Unicode は 16 ビット固定幅文字エンコード標準です。
文字列変換のコード ページを設定する

この記述は、僕を悩ませました。UCS-2とUTF-16のどちらが正しいのか。さらに調べた結果、そもそもUCS-2とUTF-16というのは、似ているようで全然違うものということが分かりました。(カテゴリが違うと言いますか、うまく表現できないですが。)

UCS-2とUTF-16はどう違うのか?

UCS-2は、文字集合、いわゆる文字コードセットです。一方、UTF-16は、エンコーディング方式です。この違いを僕は理解できていませんでした。

ユニコードが採択されることになった多言語用の文字コードセット,ISO-10846-1は,16ビット(16桁の二進数)でそれぞれの文字を表します。それをUCS-2 (Universal Character Set coded in 2 octets,「2つのオクテットでコードされたユニバーサル文字セット」)と称します。オクテットとは文字長の単位としての8ビット(8桁の二進数)のことです。

UTF (Unicode (or UCS) Transformation Format)とは,これらUCS-2または UCS-4として定義された文字をバイト列(しかし本質的にはビット列かな)としてどのように表現するかの方式を指し,複数の方式があります。
http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm

つまり扱える文字の範囲を定義しているのが、UCS-2と呼ばれる文字コードセットで、実際コンピュータ上でどう表現するかという部分では、UTF-16というエンコーディング方式が用いられています。

サロゲートペア

今まで、僕はクラシックASPの内部文字コードはUCS-2だと思い込んでいました。それなのに、UCS-2では、表現できないはずのサロゲートペアの文字をサーバに送信すると、正しく表現できている理由がよくわからなかったのです。
その理由は、内部のエンコーディング方式にUTF-16LEを採用しているため、UCS-2範囲外の文字をサロゲートペアとして表現できるというものでした。

UTF-16では,UCS-4にあってUCS-2にない文字のうち,U+10000からU+10FFFFの範囲を,(unicode consortiumのいうところの)サロゲートペアとして表します。すなわち,U+D800からU+DBFFまでの文字を上位サロゲート(high surrogate)とし,U+DC00からU+DFFFまでの文字を下位サロゲート(low surrogate)として,2つの組み合わせて表現します。そのため,UTF-16では,UCS-4のU+110000以降の文字を表現することができません。
http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm

まとめ

だいぶ長くなってしまいましたが、自分の結論は、こうです。
文字コードセットはUCS-2。そして、エンコーディング方式にはUTF-16LEが使われています。
内部エンコーディング方式がUTF-16LEであるため、クラシックASPでもサロゲートペアの文字は扱うことができます。