UTF-16
UnicodeがBMP(基本多言語面)での収録を目指していたが納まらなくなったためUnicode 2.0で16bit x2で21bit空間を表現できるようUCS-2を拡張した形式
Javaなども内部コードが16bitのためJDK 5からUTF-16に対応している
情報交換にはUTF-8が使われる場合が多く、UTF-16は内部コードとして利用される事が多い。
U+0000 .. U+FFFF 16bit
U+10000 .. U+10FFFF は 20bit で指定可能、サロゲートペアで2つの文字コードに分割する。
0x10000 を引いて 0x00000 から 0xFFFFF の20bitに収める
10bit x2 で0xD800 .. 0xDBFF の10bit と 0xDC00 .. 0xDFFF の10bitに分割する
U' = U - 0x10000
U' = yyyyyyyyyyxxxxxxxxxx
W1 = 110110yyyyyyyyyy
W2 = 110111xxxxxxxxxx
UTF-16BEはBigEndian (インターネット等の整数の並び)
UTF-16LEは1文字のバイト順が逆になったLittle Endian (Intel系などの整数の並び)
charsetにUnicodeのバージョン情報は含めない
文字コード判定のためのいろいろ
BOM
UTF-16はLittle EndianとBig Endianで並び順が変わる場合があるのでBOMをつけて区別することがある
インターネットではネットワークバイト順序と呼ばれるBig Endian またはUTF-8を使う場合が多いがそれ以外の場合もあるため
UTF-16の場合はどちらも許容するので最初に判定のための文字を追加することができる。U+FEFF が幅0のスペース文字ということと、使えない文字U+FFFEと区別できるという意味でBOMとして使われる。デコードの段階で取り除く。
文字コードの自動判定では他の文字コードでデコードした場合にXSSなどで危険なので文字コードは指定するのが基本ということで、UTF-16BE,UTF-16LEの場合には使わない。UTF-8の場合もネットワークバイトオーダーなど必要ないので使わない。Microsoftが文字コード判定のためなどでUTF-8にも使っていたが、スクリプトなどが動かない、アブナイ&反対派も多く使わない方向に向いていたりする。JSONなどでは禁止が明記されている。
XML,HTMLなどではUTF-8とUTF-16の判定方法などがあった。情報交換用のUTF-8を使うか、charsetを指定しておこう。
1996-10-15 ISO/IEC 10646-1:1993 Amd 1:1996 https://www.iso.org/standard/26222.html UTF-16
2000 RFC 2781 UTF-16 Unicode 3.0 ISO 10646-1 Annex Q