真 もわ爛漫

しゃーら、しゃーらしゃーら

Unicode, UTF-8, UTF-32

なんか色々勘違いしていたことが分かったのでメモ

元々16ビットの文字集合で全ての文字の網羅を目指して開発されたが、符号位置[1]が圧倒的に足りず、Unicode 2.0以降では21ビットの文字集合として規定されている。現在のUnicodeの空間はU+0000〜U+10FFFFである。
Unicode - Wikipedia

irb(main):002:0> printf "0x%x\n", 0b1000000000000000000000
0x200000
=> nil

21bits だが21bits目が立ったものでも半分も使ってない、ということか

ASCII文字と互換性を持たせるために、ASCIIと同じ部分は1バイト、その他の部分を2〜6バイトで符号化する。4バイトのシーケンスでは 21bit(0x1FFFFF)まで表現することができるが、Unicodeの範囲外となる17面以降を表すもの(U+10FFFFより大きなもの)は受け付けない。また5〜6バイトの表現は、ISO/IEC 10646による定義[2]とIETFによるかつての定義[3]で、Unicodeの範囲外を符号化するためにのみ使用するが、Unicodeによる定義[4]とIETFによる最新の定義[5]では、5〜6バイトの表現は不正なシーケンスである。

ビットパターンは以下のようになっている。

0xxxxxxx                                               (00-7f) 7bit
110yyyyx 10xxxxxx                                      (c0-df)(80-bf) 11bit
1110yyyy 10yxxxxx 10xxxxxx                             (e0-ef)(80-bf)(80-bf) 16bit
11110yyy 10yyxxxx 10xxxxxx 10xxxxxx                    (f0-f7)(80-bf)(80-bf)(80-bf) 21bit
111110yy 10yyyxxx 10xxxxxx 10xxxxxx 10xxxxxx           (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf) 26bit
1111110y 10yyyyxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf) 31bit

UTF-8 - Wikipedia

UTF-8 で表現できる範囲の方が広いのねん。前UnicodeのコードポイントからUTF-8に落とすコードを書くときにUTF-8の5バイト目と6バイト目について考慮してた気がするが、無駄だった、と。

めんどくせ