Web技術勉強会 第34回
       文字コードについて


          Ryuichi TANAKA.
Blog: http://blog.livedoor.jp/mapserver2007/
         Twitter: @mapserver2007
UTF-8とUTF-16とUnicode
全部別物
この際勉強しよう!
発端

文字コードは複雑
Unicodeって何?UTF-8とは違う?
用語の確認

UCS(UCS-4)
 Universal Character Set
 コードテーブルは0~0x7FFFFFFF(約21億
 文字分)
 1文字あたり4バイトを使用することから
 UCS-4とも呼ばれる文字集合
用語の確認

UCS-2
 0~0xFFFF(65535文字分)
 16ビット以上の範囲の文字は扱えない
用語の確認

Unicode
 UCSの0~0x10FFFF(約111万文字分)を使
 用
 UCSとUnicodeは策定しているグループが
 違うが、UCSとUnicodeは同じ意味で扱わ
 れることがある
用語の確認

Unicode
 Unicodeは元々16ビットですべての文字を
 表そうとしたのが始まり。
 無理にきまってんだろjk
 これだからシングルバイト圏の人間は。
用語の確認

Unicode
 現在ではUnicodeは1文字4バイトで表現さ
 れる
 1文字4バイトはUCS(UCS-4)と同じだが、
 使用範囲が限定されている
 Unicodeは00群0F面まで
 定義上の最大は127群255面まで
用語の確認

UTF-16
 UCS-2にサロゲートペアを併用した符号法
 元々は16ビットの固定長の符号
 サロゲートペアを併用することで大幅に使
 用範囲が増えた
用語の確認

UTF-16
 UTF-16ではファイルの先頭にBOMをつけ
 る
 UTF-16ではUCS-2の範囲外の文字
 (=UCS-4から持ってくる)のうち、
 0x10000~0x10FFFFをサロゲートペアとし
 て表す
用語の確認

サロゲートペア
 UTF-16で採用されたUnicodeの符号化法
 の一つ
 サロゲート文字(≠サロゲートペア)として上
 位、下位それぞれ1024文字割り当てている
用語の確認

サロゲートペア
 16ビットUnicodeの未定義領域の1024文字
 を2つ使用する
 上位サロゲートは0xD800~0xDBFF
 下位サロゲートは0xDC00~0xDFFF
 これらを組み合わせたものをサロゲートペ
 アと呼ぶ
用語の確認

サロゲートペア
 1024x1024=1048576文字を256x256の面
 (Plane)に分割、16面+BMP(Basic
 Multilngual Plane=基本多言語面=最もよく
 使う基本的な文字・記号がほぼすべて含ま
 れる領域=0x0000~0xFFFF)の計17面、約
 111万文字が使用可能になる
用語の確認

BOM
 Byte Order Mark
 UTF-16(UTF-8にもつけられる)の先頭に
 つけるU+FEFE(0xFEFE)のこと
 UTF-8ではEF BB BF
 BOMがつくとリトルエンディアン
 BOMがつかないとビッグエンディアン
用語の確認

UTF-8
 1文字を1~6バイトの可変長バイト列で表
 現する符号法
 サロゲートペアを用いない
 広大な範囲を持つが、現在の標準仕様
 (RFC3629)では使用範囲が0~0x10FFFF
 のみに規定されている
用語の確認

UTF-8
 BOMがつけれれる
 BOMをつけたUTF-8はUTF-8Nと表記
 しかし、国際的には認められていない
 使われるのは国内のみ
まとめると範囲は




  UCS-2⊆UTF-16⊆UTF-8(現行)
    ⊆(UCS-4⊆真のUTF-8)
これだけ分かれてる。
ややこしいんじゃぼけー
直近、俺らが困りそうなこと
サロゲートペア問題
サロゲートペア問題

 サロゲートペア領域とUTF-16のデフォルト領
 域はビット数が違う
  UTF-16のデフォルト:16ビット
  サロゲートペア領域:32ビット
つまり、デフォのUTF-16領域にある文字列は「2バイト」、サロ
      ゲートペア文字は「4バイト」になる。
 これは実に重大な問題を引き起こすので無視できない。
           特にWebアプリで。
<html>
<head>
<script>
function length(e) {
  alert(e);
  alert(e.length);
}
</script>
</head>
<body>
<input type="button" onclick="length('u3042');"
value="&#x3042;"/>
<input type="button" onclick="length('u20B9F');"
value="&#x20B9F;"/>
</body>
</html>
あら不思議。
  「あ」は1文字扱いなのに
「叱」は2文字扱いになっちゃった
これがサロゲートペアを扱う時の問題点。
例えば、ユーザの入力文字を「文字数」でバリデーションす
るとき。パスワードは最低8文字以上にしないと弾くという処
          理を書いたとき。
入力フォームにサロゲートペア文字を含んでいる場合…。単に
length取っただけだと、あっさり8文字以下でも突破できちゃう。
        それをそのままDBに突っ込んだ日にゃ。
              もうめちゃくちゃ。
やっつけまとめ



・文字コード(特にUnicode関係)はわかりにくすぎる
・定義が曖昧(UCSとUnicodeの解釈が人によって違うとか)
・とりあえずサロゲートペアには気をつけろ。
・対策方法は そこら中にあるからそれを参考に!

Web技術勉強会 第34回