Logo address

Unicode あれこれ (Ⅰ)

覚書

2017/08/20

1. 表記法について

この覚書で使用されている表記法

文字コードは全て16進数で表す。Unicode Consortium が発行する文書の正式なコードポイントの表現法は

U+10FFFF
のように “U+” に続けて16進で書く。Unicode の文字コードの範囲は U+0000 から U+10FFFF である。
この表記では習慣的に少なくとも4つの16進文字('0'~'F')を大文字で書く。しかし、ここでは、文脈から文字コードであることが明らかな場合、簡単のために “U+” を省略する。
またコード列は(ここでは)
1F469:200D:2764:200D:1F469
のように “:” で区切るが、(コード列である事が文脈から明らかな場合には)通常の習慣に従って
1F469 200D 2764 200D 1F469
のように空白で区切る事もある。
範囲を表す場合(ここでは)
0000~10FFFF
のように “~” を使う。(~ の右、この例では 10FFFF を含む)
複数の文字コードを表す場合(ここでは)
FFFE,FFFF
のように “,” で区切る。

Unicode Consortium 推奨の正規表現の中では文字コードを

\u{1F469}
のように “\u” に続けて波括弧(curly bracket)の中に16進数で書かれる事がある。この利点は紛れが少ないことにある。従って、状況に応じて、この表記を使う事もある。

文字コード列を厳密に(しかも記号を使って簡潔に)表現したい場合に、しばしば正規表現が使われる。ここではその表現法の一部を借用する。借用したのは

X Y # the sequence consisting of X then Y
X* # zero or more occurrences of Y
X+ # one or more occurrences of Y
X? # zero or one occurrence of Y
(X) # for grouping
X|Y # either X or Y
.   # a code point
だけで、結合文字列などの説明で使われている。記号 “#” より右はコメントである。
X とか Y は正規表現が使われている場所で(必要に応じて)説明されているはずである。

2. Unicode

2.1. Unicode テキスト

このページでは Unicode の仮想的なテキストを話題にする。
Unicode の文字コード(character code)は (16 進数で) 0 ~ 10FFFF である。
Unicode テキストとは Unicode の任意の文字コード列である。0 ~ 10FFFF の整数の集合は (Unicode の)コード空間(codespace)と呼ばれる。これは 21bit の空間である。
コード空間の各要素は code point と呼ばれる。以下単にコードあるいは文字コードと言う。各コードは抽象文字を表している。

On a computer, abstract characters are encoded internally as numbers. To create a complete character encoding, it is necessary to define the list of all characters to be encoded and to establish systematic rules for how the numbers represent the characters.

The range of integers used to code the abstract characters is called the codespace. A particular integer in this set is called a code point. When an abstract character is mapped or assigned to a particular code point in the codespace, it is then referred to as an encoded character.

文献[3] p.29 より引用

説明に出てくる「抽象文字(abstract character)」は難しい概念である。「抽象」の理解は後回しにして、ここでは単に「文字」とする。世界中には多くの文字が存在し、既に Unicode として登録されているものもあれば、まだ登録されていないものもあるだろう。登録されコードが割り当てられているものを符号化文字(encoded character)と言う。
コード表は、コード空間の要素(code point)を符号化文字に対応づける。

図1: 符号化文字

Unicode のコード空間は議論の便宜上 Plane0 ~ Plane16 の領域に分割される(表1)。

表1: Unicode Allocation
Plane description
P0 Basic Multilingual Plane (BMP)
P1 Supplementary Multilingual Plane (SMP)
P2 Supplementary Ideographic Plane (SIP)
P3 ~ P14 Reserved
P15 Supplementary Private Use Area-A
P16 Supplementary Private Use Area-B
この表は文献[3] p.48 に載っている。Plane ごとの詳細な領域割り当ても載っている。(あるいは UCD に含まれているテキスト形式の Blocks.txt の方が実用的かも知れない)

なぜ「抽象文字」と言うのか? Unicode 標準では、例えば文字 \(c\) (ここに \(c\) は任意の抽象文字を代表している)に関しては
(a) \(c\) の字形(glyph)は問題にしない
(b) テキストの中での文字 \(c\) の果たす役割や、処理のされ方を問題にする
そのために英単語(例えば fox)の構成要素としての “x” と、数式の中で変数名として現れる “\(x\)” は違う文字と扱われる。前者は letter に、後者は symbol に分類され、そして文字コードも異なる。(役割が違うから異なる字形で描かれているのであって、その逆ではない)

Unicode の説明では、コード表はコードに文字をマップさせているのだが、“character” の意味について曖昧性を残している。

The core of a character code standard is a mapping of code points to characters, but in some cases the semantics or even the identity of the character may be unclear. Certainly a character is not simply the representative glyph used to depict it in the standard. For this reason, the Unicode Standard supplies the information necessary to specify the semantics of the characters it encodes.

文献[3] p.905 より引用

具体的に何を言っているのか注意して見ていくことにしよう。

疑問: code を character にマップしているとの言い方が妥当なのか?
character にマップされていないコードポイントが多数存在すると言う現実を考えると、
Unicode のコード表は code point の役割を定義している
と、もっと広く解釈した方が良いのではないか?

抽象文字が割り当てられていない code point が存在する。

Not all assigned code points represent abstract characters; only Graphic, Format, Control and Private-use do. Surrogates and Noncharacters are assigned code points but are not assigned to abstract characters.

文献[3] p.30 より引用

もっと具体的に言えば

などがある。(BMP に例を限った)

現実のテキストはファイルに収められ、ファイルの最小単位は 8bit(1byte) である。またテキストメッセージを送信する場合も同様である。従って、コード列を何らかの方法で byte 列に変換する必要がある。この方法には UTF-8, UTF-16, UTF-32 の3通りあるが、UTF-8 以外は淘汰されるはずである。しかし、この問題に関してはここでは取り上げない。「仮想的」と述べたのは変換前のコード列のままのテキストを話題にしているからである。

文献[3] p.18 からの引用

Plain text is a pure sequence of character codes; plain Unicode-encoded text is therefore a sequence of Unicode character codes.


注: ASCII 文字コードではコードと character の1対1対応性は自明である。ところが Unicode では複雑な事情が存在する。結合文字の存在はその中の一つである。なお、ここで “character” と書いて「文字」とは書かなかったのは、Unicode の “character” は我々ユーザーが「文字」と言っているものと、必ずしも一致しないからである。

2.2. 文字コード超入門

図2に、Unicode の一部(先頭部分)を載せる。この部分は ASCII 文字コードに対応しており、ラテン文字の基礎になっている点と、プログラミング言語の基礎になっている点で、基本的である。

図2: http:U0000.pdf

文字 “a” は、006 と書かれた列と 1 と書かれた行の交差位置にあり、“a” の下に小さく 0061 と表示されている。この 0061 が “a” の文字コードである。16進数で表記されている。Unicode の文字コードは4桁の16進数で表現するのが習慣である。(4桁で表せない場合は、桁を追加する。最大で10FFFFである)

説明によると表に示されている文字(A,B,C など)はグリフであるとされている。

Unicode ではグリフ(glyph)とは文字(character)の視覚的な表現であると説明されている(文献[3] p.6)。日本語に翻訳すると「字形」に相当する[1]

Unicode 標準は Characters を扱うのであって、グリフは問題にしていない。

The difference between identifying a character and rendering it on screen or paper is crucial to understanding the Unicode Standard’s role in text processing. The character identified by a Unicode code point is an abstract entity, such as “latin capital letter a” or “bengali digit five”. The mark made on screen or paper, called a glyph, is a visual representation of the character.
The Unicode Standard does not define glyph images. That is, the standard defines how characters are interpreted, not how glyphs are rendered. Ultimately, the software or hardware rendering engine of a computer is responsible for the appearance of the characters on the screen. The Unicode Standard does not specify the precise shape, size, or orientation of on-screen characters.

グリフの説明

文字自体は抽象的な存在なのであるが、見えるようにするためには形を持たなくてはならない。
例えば文字 “a” にしても、様々な形(デザイン)の “a” があるのだが、そのうちの一つがコード表に例として示されているにすぎないのである。従って文字コード 0061 の文字の形は、コード表に示されている字形のもののみならず、アルファベットの小文字の “a” であると考えられる文字は全て該当するのである。

Unicode ではグリフに関する説明が含まれるのであるが、ASCII コード表にはそれに類する説明は含まれていなかったと思う。ASCII コードは 100 個に満たない図形文字(視覚的に表現できる文字)を扱っているのであり、その中では文字の字形の細かな違いを問題にする余地はなかったのである。しかし Unicode は膨大な文字を扱う。コード表で示されている文字は何であるのか、注意書きが要求されるようになったのであろう。

U0000.pdf には 0000 から 007F までが載っている。この内 0000 から 0020、および 007F は他の文字と性格がかなり異なる。他の文字のように字形を持っていない。表示装置の中で、後続する文字の配置位置を制御するのに使われているので制御文字と呼ばれている1

以下の制御文字はテキストファイルの中で次の意味を持つ。


注1: 他に「制御文字」には通信制御に使われている「文字」もある。
注2: 改行は、Windows の場合には 000D:000A 、古い MacOS (OS9 まで) は 000D である。
なお、ここでは “:”で連続した Unicode を表している。

[1] 常用漢字表における「字体・書体・字形」等の考え方について
http://kodomo.bunka.go.jp/seisaku/bunkashingikai/kokugo/shoiinkai/iinkai_14/pdf/shiryo_3.pdf

2.3. Unicode 基本文献

Unicode の標準化組織 Unicode Consortium は Unicode[2] に関する膨大な文書を発行している。これらの文書は Unicode 標準に関する全ての信頼できる情報源であると言ってもよい。
規格文書は Unicode のバージョンごとに纏められている。現在の最新バージョン 10.0.0 であるが、この記事を書いている時点(2017/07)では PDF 版の解説記事の最新版は 9.0.0 である。以下の説明は、これに基づく。

文献[3]はもっとも基本的な Unicode に関する文献である。補足的な説明が文献[4]にある。

Unicode の個別の文字について調べたい時には文献[5]が基本的でる。文字コード別に文字が分類されている。PDF ファイルであるために見やすい事は見やすいが、あまり実践的ではない。
もっと使いやすいのは文献[6]である。テキストファイルなので、grepawk を使えるのが嬉しい。

用語の日本語訳はできるだけ文献[7]に従ったが、さらに簡略化した言い方をしている場合もあるので注意されたい。

[2] The Unicode Consortium
http://www.unicode.org/

[3] The Unicode® Standard: Version 9.0 – Core Specification
http://www.unicode.org/versions/Unicode9.0.0/UnicodeStandard-9.0.pdf

[4] Unicode Technical Reports
http://www.unicode.org/reports/

[5] Unicode 10.0 Character Code Charts
http://www.unicode.org/charts/

[6] UnicodeData.txt
http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt

[7] Unicode Terminology English - Japanese
http://www.unicode.org/terminology/term_en_ja.html

3. MARK? or SIGN?

“?” は “question mark”.
“$” は “dollar sign”.

疑問: “mark” と “sign” はどのように使い分けられているのか?

3.1. UnicodeData.txt

UnicodeData.txt の一部を載せると、

001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;
001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;
0020;SPACE;Zs;0;WS;;;;;N;;;;;
0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;
0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;
0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;
0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
0026;AMPERSAND;Po;0;ON;;;;;N;;;;;
0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;
0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;

のようになっている。

このファイルのデータ構造を簡単に紹介する。

残りはここでの議論に関係が無いので省略する。

「文字区分」については

[8] Table 12. General_Category Values
http://www.unicode.org/reports/tr44/#General_Category_Values

に解説がある。

3.2. 文字区分

Unicode では表2に示すように文字を7つに分類している[8]
ここでは ASCII 文字集合(Unicode の 0000 ~ 007F )の範囲で、この分類について考えてみる。この範囲の文字コードのPDF版は次の文献[9]に載っている。

[9] C0 Controls and Basic Latin (Range: 0000~007F)
http://www.unicode.org/charts/PDF/U0000.pdf

なおここでは4桁の16進数は、文字コードを表すとする。

表2: 文字区分
abbr long name category values
L Letter Lu Ll Lt Lm Lo
M Mark Mn Mc Me
N Number Nd Nl No
P Punctuation Pc Pd Ps Pe Pi Pf Po
S Symbol Sm Sc Sk So
Z Separator Zs Zl Zp
C Other Cc Cf Cs Co Cn
ここで、

3.3. 図形文字(graphic character)

定義: 図形文字

図形文字とは形を持つ文字だと考えて良い。表2の
が該当する。平たく言えば形をイメージできるものは図形文字であると考えて良い。ただし特殊なものとしては「空白文字(Zs)」も図形文字に含める。詳しくは文献[3]の p.105 を見よ。

なお Zs に属する文字は以下の通り

% awk -F ';' '$3 ~ /Zs/ {print}' UnicodeData.txt
0020;SPACE;Zs;0;WS;;;;;N;;;;;
00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;
205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
%

3.4. MARK? or SIGN?

“MARK” とか “SIGN” とかを、まずは ASCII 文字集合の中で吟味するのであれば、“Punctuation” と “Symbol” だけが関係する。

ASCII 文字集合の中で、“Punctuation” には次の文字が含まれる。

! 0021 EXCLAMATION MARK
" 0022 QUOTATION MARK
# 0023 NUMBER SIGN
% 0025 PERCENT SIGN
& 0026 AMPERSAND
' 0027 APOSTROPHE
( 0028 LEFT PARENTHESIS
) 0029 RIGHT PARENTHESIS
* 002A ASTERISK
, 002C COMMA
- 002D HYPHEN-MINUS
. 002E FULL STOP
/ 002F SOLIDUS
: 003A COLON
; 003B SEMICOLON
? 003F QUESTION MARK
@ 0040 COMMERCIAL AT
[ 005B LEFT SQUARE BRACKET
\ 005C REVERSE SOLIDUS
] 005D RIGHT SQUARE BRACKET
_ 005F LOW LINE
{ 007B LEFT CURLY BRACKET
} 007D RIGHT CURLY BRACKET

“Symbol” に含まれるのは以下の文字である。

$ 0024 DOLLAR SIGN
+ 002B PLUS SIGN
< 003C LESS-THAN SIGN
= 003D EQUALS SIGN
> 003E GREATER-THAN SIGN
^ 005E CIRCUMFLEX ACCENT
` 0060 GRAVE ACCENT
| 007C VERTICAL LINE
~ 007E TILDE

どうやら “question mark” の “MARK” と言うのは句読点類を意味しているらしい。しかし、ならば

# 0023 NUMBER SIGN
% 0025 PERCENT SIGN
& 0026 AMPERSAND
は何故 “Symbol” ではなくて “Punctuation” に分類されているのだろう?

アクセントに関する次の文字はどうなんだろう?

^ 005E CIRCUMFLEX ACCENT
` 0060 GRAVE ACCENT
~ 007E TILDE

「文字区分」で “Mark” に属する文字を調べると、これらはアクセントマークなのである。アクセントは記号なのかマークなのか?
この3つが “Punctuation” ではなく “Symbol” に分類されたのは、文字としての現実の使われ方(1つの独立した記号として使われている)からだろうか?

結局、疑問が解けない...
MARK と SIGN はどのような基準で分けているの? → 以下の補足1と補足2を見よ

補足1:@”, “#”, “%”, “&
この話は文献[8]でも取り上げられている:

The distinctions between some General_Category values are somewhat arbitrary for edge cases, particularly those involving symbols and punctuation. For example, a number of multiple-function ASCII characters, including “@”, “#”, “%”, and “&”, have long been classified as Other_Punctuation (gc=Po), although they are not among the characters used as punctuation marks in traditional Western typography.

つまり、UnicodeData.txt では “@”, “#”, “%”, “&” は punctuation として分類されてはいるが、伝統的な西洋のタイポグラフィでは punctuation 扱いはされていないと。

補足2:^”, “`”, “~
これらの記号は U0300.pdf にも載っている。
つまり、U0000.pdf の方は、独立した1文字(つまり記号)であって直前の文字を修飾する意味を失っている。他方 U0300.pdf に現れる記号

は直前の文字を修飾し、その為に結合し、独立した1文字とはならない。

なお、0300 とよく似たものに 0340 (Vietnamese tone mark の COMBINING GRAVE TONE MARK) があるが使わないようにとの御達しである。0341 も同様。
また 0303 と形が似ているものに 0342 (COMBINING GREEK PERISPOMENI) があるが、 “Greek-specific form of circumflex for rising falling accent” と注釈されている。これは生きているらしい。ギリシャ文字の中で、0303 とは異なるニュアンスで使われているのかも知れない。

4. CHARACTER? or LETTER?

4.1. “character” は表意文字、“letter” は表音文字?

ネットで調べると「文字」の英訳として “character” と “letter” があるらしい。
そして、“character” は表意文字、“letter” は表音文字であるとされる。多分、大ザッバにはそれで良いのだろう。

実際に、Unicode での文字分類を調べると、Letter については以下のような表現に出会う。

LATIN CAPITAL LETTER
GREEK CAPITAL LETTER
HIRAGANA LETTER
KATAKANA LETTER
HANGUL LETTER

また、漢字に関しては、Unicode表[10]では “ideographs” としているが解説記事である[11]には “ideographic character” と表現されている。

これらは、“letter” は表音文字、“character” は表意文字、の解釈と矛盾していない。
しかし何だかしっくり来ないのだ。

[10] CJK Unified Ideographs (Range: 4E00~9FEA)
http://www.unicode.org/charts/PDF/U4E00.pdf

[11] Chapter 18: East Asia
http://www.unicode.org/versions/Unicode9.0.0/ch18.pdf

4.2. Unicode の “character” は本当に表意文字?

何がしっくり来ないのか? letter と character との関係である。Unicode は character code を扱っているのである。その code の中で letter が扱われている。となれば letter なるものは(集合論的には) character の一部である。「character は表意文字で... letter は表意文字ではない」とは行かないのである。

Unicode で言う character は日本語の「文字」に近い意味で語られているのではないかと思える。(いやそう考えないと辻褄が合わない)
そのために、表意文字を言い表したい場合には “ideograph” と言うのであろう。

これで一件落着? --- いや、そうでもない

4.3. Unicode で言う Letter は本当に表音文字?

前節「MARK? or SIGN?」の表2「文字区分」の中に “Letter” が存在する。そして “UnicodeData.txt” では個々の文字の文字区分が個別に示されている。CJK Ideograph については、纏めて次のようになっている。

4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
9FEA;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;

説明を繰り返すが、フィールドは “;” で区切られている。第1フィールドは文字コード、第2フィールドは説明、第3フィールドは文字区分であり、“Lo” は “Other Letter” の意味である。つまり “Letter” として分類されているのである。これはどう解釈したら良いのか?

4.4. 語句解釈の迷路

どうやら “Character” とか “Letter” を世の常識通りには受け取らない方が良いらしい。
これらの文字については、Unicode の独自の意味があって、それは歴史的に形成されたものだ。
コンピューターの誕生と共に「文字コード(character code)」が定義され、そこでアルファベットは “Letter” に分類されたと思う。そして今は多言語を扱う Unicode の時代である。Letter の意味がそれとともに変化したと考えたらよかろう。
文字が表音なのかそれとも表意なのかは文字(character)分類にとっては小さな問題なのであろう。

4.5. MEMO

表音文字 phonogram
表意文字 ideogram or ideograph

注意: phonograph は蓄音機

Phonetic symbol

5. 結合文字

5.1. 結合文字

定義: 結合文字 (combining character)

“combining mark” とも言われる。
文字区分で “Mark” とされている文字。通常は単独では使われず、結合文字の前(直前である必要はなく、直近)に現れた基底文字に作用して、修飾する。(アクセントマークを付けるとか、...)

結合文字は表[2]の文字区分 Mark の値によって3つに分類される[8]:

Mn: a nonspacing combining mark
Mc: a spacing combining mark
Me: an enclosing combining mark

ややこしいのは、紛らわしい言葉使いが、文献[8]とは別に定義されている事だ。

D53 Nonspacing mark: A combining character with the General Category of Nonspacing Mark (Mn) or Enclosing Mark (Me).

文献[3] D53 p.106

これによると “Nonspacing mark” は MnMe を含むが、“Nonspacing Mark” だと Mn だけである。"nonspacing combining mark" は後者の意味である。従って意味するところを “Mn” や “Me” を使って必ず補足すべし。

定義: 基底文字(base character)

結合文字以外の図形文字

5.2. 「ダ」問題

カタカナは http:U30A0.pdf に含まれている。先頭部分を図に示す。

図3: http:U30A0.pdf

Unicode 表の PDF ファイルには表だけではなく、個々の文字に関する説明も含まれている。

図4: 「タ」と「ダ」の説明

図4に現れる「≡」は等価(equivalence)を表している。つまり「ダ」は一つのコード(30C0)で与えてもよいし、2つの連続したコード(30BF:3099)で与えてもよい。「ダ」は単なる例であって、全ての濁点および半濁点付きの平仮名・片仮名に同様に2種類の表現法が成立する。コード 3099 は濁点を表す結合文字である1。結合文字と言うのは、他の文字と結合して新しい文字を形成する符号のことである。半濁点を表す結合文字 309A も存在する。図5から分かるように、独立した1文字2として濁点を表す 309B や半濁点を表す 309C も存在する。

図5: http:U3040.pdf

ここで取り上げた「ダ」問題は多分に誤解を招いたかも知れない。

結合文字を導入する意図が見えてこない。

結合文字を導入した結果が、結合文字なしの1コードで表現できるならば結合文字を導入するメリットは何か? 複雑さを増やしただけではないか?

結合文字を導入するメリットがあるとすれば、新しい字形を生み出す力である。例えば、「タ」に半濁点を添えることは形式的に可能である。それが意味を持つか否か、意味を持つとしてもフォントが存在するか否かは別の問題である3。でも或る作家が出版社に対して、(登場人物の癖のある発音を表現するために)似たことを要求するかも知れない。

結合文字を導入する意図はラテン文字の扱いを見ると見えてくる。


注1: 濁点を表す結合文字は “COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK”、半濁点を表す結合文字は “COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK” と名付けられている。(U3040.pdf)
注2: 「独立した1文字」の定義は実は非常に難しい。ここでは1文字分のスペースをとると言う意味で使われている。
注3: アイヌ語のカナ表記に「ト゚」が存在し、コード列 30C8:309A で生成される。「ト゚」は Chrome、Safari、Firefox でサポートされている。(IE は確認していない)
「タ゚」はアイヌ語のカナ表記に存在しない。コード列 30BF:309A で生成される文字の見え方はブラウザに依存している。Chrome と Firefox は OK だが、Sadari は半濁点の後のスペースの取り方が NG である。

5.3. ラテン文字とアクセントマーク

ラテン文字にはしばしばアクセントマーク(accent mark)が現れる。

図6に、そうしたアクセントマーク付き文字の一部を示す。コードが8bitで収まるので、これらはASCII文字コード表と共に広く使われてきたのではないかと思える。

図6: http:U0080.pdf

アクセントマーク付きのラテン文字は次のPDFファイルに現れる。

2つのアクセントマークが付いたラテン文字も存在する。

アクセントマーク付きのラテン文字は結合文字を使っても表現できる。2つのアクセントマークが付いている場合には2つの結合文字を使って表現すると考えるのが自然である。

図7はラテン系のアクセントマークのテーブルである。(全てではない)

図7: http:U0300.pdf

点線で表された円がアクセントマークが作用する文字を表している。

図7の結合文字 03100352 で表されているアクセントマークは、2つの要素から構成されているように見えるが、これで1つのアクセントマークであり、分解はできないとされている。他方結合文字 0344 は2つの結合文字 0308 および 0301 を順次作用させたものと等価であるとされている1


注1: つまり結合文字 0344 は要らないはずである。何故このようなものが入り込んでしまったのか? 原理原則が unicode.org で煮詰まっていない時代に入り込んだのだろうと思われる。存在しなくても良い、あるいは存在しないほうが良い文字コードはこの他にもいくつかある。この事は2つの文字の同一性の判定を幾分複雑にする。

5.4. 囲みマーク

ちょっと変わった結合文字の例が文献[3] p.56に載っている。

さらに p.112 には

呟き: 図形を描かない囲みマークが欲しい... グルーピングに使える

20DF,20E0,20DD などは結合囲みマーク(combining enclosing mark)と呼ばれ、囲み文字を生成する。このようなものの存在は文字の正規化を複雑にしている。後に触れる。

囲みマークで生成された文字は記号のように見えるが、必ずしも記号ではない。その事が文献[3] p.57 に次の図で示されている。

文字 “!” (0021) と囲みマーク 20E4 から生成された文字の特性(property)はベースになった “!” と同じであるとされている。従って句読点文字(punctuation character)であり、記号ではない。記号と句読点文字とでは改行時における禁則処理の方法が異なる。警告マーク(文字 “!” を三角形で囲った記号)はニーズとしてはあるので、記号としての警告マークが 26A0 として別に準備されている。

この例は、同じ字形をしているからと言って同じ文字とは限らない事を示している1。使い方まで問題にされているのである。


注1: 同様な事例は Mathematical Alphanumeric Symbols (http:U1D400.pdf)にも見られる。
数式に出てくる「\(a\)」(1D482) は記号であり、Letter である「a」(0061)とは違う。後者は語(word)の構成要素として使われるが、記号は単独に使われる。グリフは例示に過ぎない事に注意。

5.5. 結合文字は文字か?

文献[3]には “combining character” と “combining mark” の2種の言い回しが見られるが、この2つの用語はどのように使い分けられているのか?

次の説明がある。同じと見て良いだろう。

Combining character: A character with the General Category of Combining Mark (M).

文献[3] p.105 より引用

combining character の使い方

All combining characters can be applied to any base character and can, in principle, be used with any script.

文献[3] p.55 より引用

script: 文献[7]では「用字」と訳している。"Cyrillic script" とか “Latin script” のような使い方をする。言語ごとの文字集合とその使い方と理解すれば良いだろう。(詳しくは tr24)

base character:

Any graphic character except for those with the General Category of Combining Mark (M).

文献[3] p.105 より引用

表2の中の、Letter (L)、Number (N)、Punctuation (P)、Symbol (S)、Space Separator (Zs)を指す。

combining character は

私見

“combining character” は文字の断片に過ぎず、これを character の部分集合と見なすには問題がある。
例えば「テキストの中の character の個数を数えなさい」と言われた場合、困る。
“combining mark” に統一し、概念としては “character” から外すのが分かりやすいのではないか?
“combining mark” の和訳 → 「結合符号」で良いのではないか?
ついでに、制御文字類も “character” から外すのが分かりやすい。
そのようにすれば “character” は日常用語の「文字」(グリフの1文字)に近くなる。
ただし「グリフの1文字」は吟味を要する言い方である。
「グリフの1文字」は、日本語や英語(or Latin)でははっきりしているが、世界中の文字の中には怪しいものもあるのではないか?

そもそも「文字コード表(character code table)」と言うから分かり難くなるのだ。
“Unicode 10.0 Character Code Charts” → “Unicode 10.0 Code Charts”
と呼ぶべし。


注1: 制御文字類: carriage return, tab, or right-left mark など
注2: 文献[3]の “Exhibiting Nonspacing Marks in Isolation” を見よ

5.6. 結合文字列

Unicode テキストはコードポイントの列である。結合文字の存在は 2つの Unicode テキストの同等性の比較を複雑にする。結合文字列の概念は、この問題の解決のために導入されている。Unicode テキストは結合文字列を単位として細分化し、結合文字列を単位として両テキストと比較する。(→ Unicode normalization)

定義: 結合文字列(combining character sequence)

Combining character sequence: A maximal character sequence consisting of either a base character followed by a sequence of one or more characters where each is a combining character, zero width joiner, or zero width non-joiner; or a sequence of one or more characters where each is a combining character, zero width joiner, or zero width non-joiner.

p.107

CCS := BC? (CC|JC)+
DCCS := (CC|JC)+
CCS: combining character sequence
DCCS: defective combining character sequence
BC: base character
CC: combining character (Mn,Mc,Me)
JC: join control1er (ZWNJ|ZWJ) # (200C,200D)

注意: 「結合文字列」と言えば、結合文字の列のように聞こえるが、通常は base character を先頭に含む。もっと適切な言葉が欲しい。

注釈: 結合文字列の定義の中に ZWJ(zero width joiner) と ZWNJ(zero width non-joiner) が含まれている。これらは一般に Letter に作用する。結合文字列の中でどのように使われるのか? 例が文献[3]の Chapter 12 に含まれている。しかし我々には馴染みの無い script なので理解しずらい。

\(X\) を結合文字列の集合とする。この時、\(f(X)\) は
\[ \{\mbox{encoded character}\} ⊂ f(X) ⊂ \{\mbox{abstract character}\} \]
の関係を満たす。ここに \(f\) はコード表である。

\(f(X)\) について呼称が欲しいが...

図8: 結合文字列から得られる文字

コメント:
「合成基底文字」のような概念を次のように BNF(Backus-Naur form) で定義する

合成基底文字 := 基底文字 | (合成基底文字:結合文字類)
ここに “:” はコードが連なることを表す。
このようにして「合成基底文字」を定義しておくと、結合文字類が作用する相手は直前の合成基底文字であることを正確に表現できるのではないかと思えるのだが...

結合文字列に類似の概念がありすぎる!

たぶん「合成文字」のような言葉が必要なのだろう。

定義: 拡張基底文字(extended base character)

EBC := BC|HAN
EBC: extended base character
BC: base character
HAN: Hangul syllable (or Hangul Jamos)

注釈: Hangul syllable (or Hangul Jamos)
テキストを処理するプログラムの input は任意のコード列と考えるべきである。つまり必ずしも正当なコード列ではない。不正なコードが含まれている場合はプログラムは何らかのエラー処理をしなくてはならない。Hangul black はコード列なので、正当なコード列(Standard Korean syllable block)のシンタックスと、正当なコード列ではないが拡張基底文字とみなせるコード列のシンタックスは異なっていることに注意する必要がある[13]。ここでは、この問題に触れていない。(他の場所で取り上げる)
注意: このように書くと BC (base character) には Hangul が含まれていないかのように聞こえるが、合成済み Hangul は base character に分類されている。さらに Hangul Jamo も基底文字に分類されていることに注意する必要がある。
Hangul Jamo による Hangul の表現では、複数の基底文字(Hangul Jamo)の列が1つの基底文字のように見え(振舞わ)なくてはならない。これは(これまでの)基底文字の定義から逸脱している。そのために、基底文字の概念拡張が必要とされるのである。

定義: 拡張結合文字列(extended combining character sequence)

ECCS := EBC? (CC|JC)+
ECCS: extended combining character sequence
EBC: extended base character
CC: combining character (Mn,Mc,Me)
JC: join control1er (ZWNJ|ZWJ) # (200C,200D)

結合文字列(combining character sequence) は文字か?

A: That depends. For a programmer, a Unicode code point represents a single character (for exceptions, see below). For an end user, it may not. The better word for what end-users think of as characters is grapheme: a minimally distinctive unit of writing in the context of a particular writing system.

文献[12]より

[12] Characters and Combining Marks
http://unicode.org/faq/char_combmark.html

6. 書記素

書記素(grapheme): ある言語の書記体系の最小単位;英語のアルファベットの各文字など. (Goo 辞典より)

ユーザ認知文字(user-perceived character)

ユーザが1文字と考えているもの(ユーザ認知文字)は必ずしも 1 つのコードポイントに対応しない。次の書記素クラスタに近い。

書記素クラスタ(Grapheme cluster)

It is important to recognize that what the user thinks of as a “character”—a basic unit of a writing system for a language—may not be just a single Unicode code point. Instead, that basic unit may be made up of multiple Unicode code points. To avoid ambiguity with the computer use of the term character, this is called a user-perceived character.
...
These user-perceived characters are approximated by what is called a grapheme cluster, which can be determined programmatically.

文献[13]

我々がテキストを編集する時に1文字として扱いたいものと考えてよい。
普通の文字の他に、改行やタブなども編集対象になるであろう。

補注: grapheme cluster
“grapheme cluster” は書記素を表すコード列である。(書記素の列ではない)
ここでは “grapheme cluster” を定義しているのではなく、概念を説明しているだけである。
日本語では書き言葉の最小単位は文字であり、人々は1文字とは何であるか(教育の結果)認識していると思える。例えば漢字の「明」を構成する「日」と「月」を分離して書くわけにはいかないことなど。
Windows の改行(CR+LF)は、内部の2つの文字を分離させてはならない。まとめて書記素として扱う必要がある。
半角片仮名の「ガ」も書記素として扱われる。(次の grapheme extender の定義を見よ)
そのために、マウスカーソルが「カ」と「 ゙」の間に入らない。

定義: grapheme extender

A grapheme extender can be conceived of primarily as the kind of nonspacing graphical mark that is applied above or below another spacing character.

文献[3] D59 p.108

GE(grapheme extender) は

GE := (NM|JC|\u{FF9E}|\u{FF9F}|SMC)
GE: grapheme extender
NM: nonspacing mark (Mn,Me)
JC: join control1er (ZWNJ|ZWJ) # (200C,200D)
SMC: a few spacing mark for compatibility
\u{FF9E}: HALFWIDTH KATAKANA VOICED SOUND MARK
\u{FF9F}: HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK

注釈: grapheme extender の一覧は文献[14] DerivedCoreProperties.txt に “Grapheme_Extend” として載っている。この中には spacing mark Mc が 26個含まれている。(UnicodeData.txt 全体で 401個)
またタグ文字 E0020~E007FCf に属するが、GE に含まれている。"strongly discouraged" とある。
“grapheme extender” に関する説明は分かりにくい。"extender" だから何かに作用すると思えるが、何にどのように作用するのか説明が見つからない。多分 grapheme base に後ろから作用するのだと思えるが... 作用で生成されたものが Legacy grapheme cluster になるように思えるが、明示的な説明が無い。 → この理解でよい。文献[13]
スタック・オーバーフローに
“What is the difference between ‘combining characters’ and ‘grapheme extenders’ in Unicode?”
の議論がある。何か参考になるかも知れない。
https://stackoverflow.com/questions/21722729/what-is-the-difference-between-combining-characters-and-grapheme-extenders-i

定義: grapheme base

Grapheme base: A character with the property Grapheme_Base, or any standard Korean syllable block.

文献[3] D58 p.107

The set of characters with the Grapheme_Extendproperty and the set of characters with the Grapheme_Base property are disjoint, by definition.

文献[3] D59 p.108

GB := GC - GE		# "-" is a subtraction of sets
GB: grapheme base
GC: graphic character
GE: grapheme extender

書記素クラスタには2種ある。一般に拡張書記素クラスタが推奨される。

定義: Legacy grapheme cluster/p>

A legacy grapheme cluster is defined as a base (such as A or カ) followed by zero or more continuing characters. One way to think of this is as a sequence of characters that form a “stack”.

The base can be single characters, or be any sequence of Hangul Jamo characters that form a Hangul Syllable, as defined by D133 in The Unicode Standard, or be a pair of Regional_Indicator (RI) characters. For more information about RI characters, see [UTS51].

The continuing characters include nonspacing marks, the Join_Controls (U+200C ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER) used in Indic languages, and a few spacing combining marks to ensure canonical equivalence. Additional cases need to be added for completeness, so that any string of text can be divided up into a sequence of grapheme clusters. Some of these may be degenerate cases, such as a control code, or an isolated combining mark.

文献[13]

LGC := CRLF | (GB|HAN|RI) (GE)* | .
LGC: legacy grapheme cluster
CRLF: 000D:000A
GB: grapheme base
HAN: a Hangul syllable (or Hangul Jamos)
RI: a pair of regional indicator
GE: grapheme extender

注意: 引用した説明を読む限り、LGC の定義は “(GE)*” ではなく、“(NM|JC|SMC)*” なのであるが、文献[13]の
Table 1b. Combining Character Sequences and Grapheme Clusters
を見る限り、“(GE)*” が正しい。(こちらの方が正確)

注釈: any sequence of Hangul Jamo characters
Hangul Jamo の中には古い Hangul を構成する部品も含まれている。古い Hangul にはコードポイントが与えられていないので、 Legacy grapheme cluster で構成可能であることを言いたいらしい。
注釈: CRLF
Windows の改行 CRLF は2文字で1つの編集単位であるから grapheme cluster に含めておく必要がある。
1文字の全ての制御文字もまた同様である。
注釈: regional indicator
コードポイント 1F1E6~1F1FF は RI 用に A~Z を表す。日本は JP なので RI は 1F1EF:1F1F5。これで日本の国旗 🇯🇵 が表示される。

定義: 拡張書記素クラスタ(Extended grapheme cluster)

An extended grapheme cluster is the same as a legacy grapheme cluster, with the addition of some other characters. The continuing characters are extended to include all spacing combining marks, such as the spacing (but dependent) vowel signs in Indic scripts. For example, this includes U+093F ( ि ) DEVANAGARI VOWEL SIGN I. The extended grapheme clusters should be used in implementations in preference to legacy grapheme clusters, because they provide better results for Indic scripts such as Tamil or Devanagari in which editing by orthographic syllable is typically preferred. For scripts such as Thai, Lao, and certain other Southeast Asian scripts, editing by visual unit is typically preferred, so for those scripts the behavior of extended grapheme clusters is similar to (but not identical to) the behavior of legacy grapheme clusters.

文献[13]

EGC := CRLF | (GB|HAN|RI) (GE|SM)* | .
EGC: extended grapheme cluster
CRLF: 000D:000A
GB: grapheme base
HAN: a Hangul syllable (or Hangul Jamos)
RI: a pair of regional indicator
GE: grapheme extender
SM: spacing mark (Mc)

注釈: U+093F
093F は spacing mark である。母音記号。母音が子音の左に来るのは、左から右に読むからであろうと思ったのであるが、調べてみると左から右に書くらしい。不思議である。
“Legacy grapheme cluster” と “Extended grapheme cluster” の主な違いは、前者が結合文字として(少数の例外を除いて) non-spacing mark のみであるが、後者は spacing mark をも含めるところにある。(より、一般的になっている)

以上を纏めると次の図のようになる。(制御文字を除く)

図9: Extended Grapheme Cluster (推定図)

注意: prepended concatenation mark
最近(2015) Prepended_Concatenation_Mark が導入された[15]。これを含めると EGC のシンタックスは
EGC := PCM* (GB|HAN|RI) (GE|SM)*
PCM: prepended concatenation mark
となる。
この属性を持つ文字の一覧は PropList.txt にある。

[13] UAX #29:UNICODE TEXT SEGMENTATION
http://www.unicode.org/reports/tr29/

[14] DerivedCoreProperties.txt
http://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt

[15] New Character Property for Prepended Concatenation Marks
http://blog.unicode.org/2015/11/new-character-property-for-prepended.html

7. 接合子

接合子(joiner)

接合子は文字合成のための演算子である。

現状では接合子は(Mac においてさえ)十分にサポートされているようには見えない。その事が理解を困難にしている。(実験で動作を確認できない😔)

7.0.1. ゼロ幅接合子/ゼロ幅非接合子

ゼロ幅接合子(Zero width joiner):

U+200D zero width joiner is intended to produce a more connected rendering of adjacent characters than would otherwise be the case, if possible.

文献[3] p.828

ゼロ幅非接合子(Zero width non-joiner):

U+200C zero width non-joiner is intended to break both cursive connections and ligatures in rendering.

文献[3] p.829

ゼロ幅接合子とゼロ幅非接合子は書式制御文字である。

zero width joiner and zero width non-joiner are format control characters.

文献[3] p.831

注釈: “zero width joiner” や “zero width non-joiner” は、文字を表示する場合の Ligature や 草書体(cursive)における続け字を制御している。であるから一般に
Letter 200D Letter
Letter 200C Letter
のようにコードが続く。特殊な使い方としては
Letter 200D 200C Letter
Letter 200D 200C 200D Letter
がある。文献[3] pp.828-831

7.0.2. Combining Grapheme Joiner

Combining Grapheme Joiner:

U+034F combining grapheme joiner (CGJ) is used to affect the collation of adjacent characters for purposes of language-sensitive collation and searching. It is also used to distinguish sequences that would otherwise be canonically equivalent.

Formally, the combining grapheme joiner is not a format control character, but rather a combining mark. It has the General_Category value gc=Mn and the canonical combining class value ccc=0.

As a result of these properties, the presence of a combining grapheme joiner in the midst of a combining character sequence does not interrupt the combining character sequence; any process that is accumulating and processing all the characters of a combining character sequence would include a combining grapheme joiner as part of that sequence. This differs from the behavior of most format control characters, whose presence would interrupt a combining character sequence.

文献[3] p.831

注釈: Combining Grapheme Joiner は Wikipedia(日本語版) では「図形素結合子」と訳している。しかし “Grapheme” を「書記素」と訳し、“Jointer” を「接合子」として訳すのであれば、「書記素接合子」として訳した方が良かろう。
“combining” の修飾子は、combining character に属している事を強調したいからか? 修飾子無しの “Grapheme Joiner” なるものが別に存在しないので要らないのではないか? あいるは将来予定されているのか?
また同 Wikipedia には、『文字名称の上では「結合子」となっているが、文字を結合するのではなく、むしろ結合しないことを表す』と書かれている。見かけ上結合しているだけよ... との意味らしい。
このようなものが必要となるのは、複数の文字の組みで(事実上)1文字を表す文字体系が存在するから。(例えばスロバキア語の"CH")
疑問: CGJ は Mn に属しているから CCS を終了させないと言っている。ならば ZWJ や ZWNJ は終了させるのか?

% grep JOINER UnicodeData.txt
034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;;
200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
2060;WORD JOINER;Cf;0;BN;;;;;N;;;;;
2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;;
1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;
11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;;
11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;;
%

7.0.3. ゼロ幅接合子による表現例

例 1: 1F468:200D:1F4BB

# man technologist
# fallback

fallback とは、合体図形が無い場合の代替え図形

このブラウザでの 1F468:200D:1F4BB の見え方: 👨‍💻

注釈: ブラウザでの見え方
むしろブラウザが動いているシステムでの見え方と言うべきである。フォントはブラウザではなくシステムの問題だから...
1F468 の意味は “MAN” であり、1F4BB の意味は “PERSONAL COMPUTER” である。これらは、意味を崩さない範囲で自由にデザインできる。また、この2つから生成される合体図形も、“MAN” with “PERSONAL COMPUTER” の範囲で自由にデザインできる。送られてきたメールに Mac の絵文字が入っていても、送信者が Mac から送った保証はない。

% grep '^(1F468|200D|1F4BB)'  UnicodeData.txt
200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
1F468;MAN;So;0;ON;;;;;N;;;;;
1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
%

例 2: 1F469:200D:2764:200D:1F469

図10: 文献[19]

このブラウザでの 1F469:200D:2764:200D:1F469 の見え方: 👩‍❤‍👩

% grep '^(1F469|200D|2764)'  UnicodeData.txt
200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;
1F469;WOMAN;So;0;ON;;;;;N;;;;;
%

Mac のテキストエディタでは1文字として扱われている。

When an emoji zwj sequence is sent to a system that does not have a corresponding single glyph, the ZWJ characters are ignored and a fallback sequence of separate emoji is displayed.

文献[19]より引用

要約


注1: 接合子が作用する相手の正確な説明が欲しいが... どこにあるか分からない。

[16] Emoji
http://www.unicode.org/press/emoji.html

[17] Recommended Emoji ZWJ Sequences, v5.0
http://unicode.org/emoji/charts/emoji-zwj-sequences.html

[18] Full Emoji List, v5.0
http://www.unicode.org/emoji/charts/full-emoji-list.html

[19] UNICODE EMOJI
http://www.unicode.org/reports/tr51/

8. Appendix

8.1. UTF-8

x in [00000000.00000000.0bbbbbbb] → 0bbbbbbb
x in [00000000.00000bbb.bbbbbbbb] → 110bbbbb,10bbbbbb
x in [00000000.bbbbbbbb.bbbbbbbb] → 1110bbbb,10bbbbbb,10bbbbbb
x in [000bbbbb.bbbbbbbb.bbbbbbbb] → 11110bbb,10bbbbbb,10bbbbbb,10bbbbbb
b0 or 1

上から順に in を評価し、YES ならそこで byte 列を生成し、それを答えとする。
逆(UTF-8 から Unicode の生成)は気を付ける必要がある。
何故なら の右は全ての b の値が許されるわけでは無いから。不正の UTF-8 表現は排除する必要がある。
たとえば

1100000b,10bbbbbb
は許されない。なぜなら、これは
0bbbbbbb
で表現すべきだから。

変換上の注意: surrogate pair は禁止

The definition of UTF-8 prohibits encoding character numbers between U+D800 and U+DFFF, which are reserved for use with the UTF-16 encoding form (as surrogate pairs) and do not directly represent characters.

テキストファイル、通信プロトコル、で使われる。
実際の処理は unsigned integer に変換されることが多い。(UTF-32 に変換したと言ってもよい)
例えばテキストエディタ

Plan9 manual utf(6)

UTF-8, a transformation format of ISO 10646
https://tools.ietf.org/html/rfc3629

8.2. Surrogate Pair

surrogate pair は UTF-16 にのみ許される。16bit 空間では不足したので導入された苦肉の策だろう。surrogate pair の導入によって、UTF-16 は 21 bit までのコードを扱えるようになった。Unicode Consortium はコード空間をこれ以上に大きくしないと約束している。

Unicode を Surrogate pair へ変換するアルゴリズムは
文献[3] p.124 に説明されている。
簡単に言えば(bit表現で)

uuuuuxxxxxxxxxxxxxxxx → 110110wwwwxxxxxx 110111xxxxxxxxxx
wwww = uuuuu -1
である。(uuuuu は plane を表している)
1101(2)=D(16)
例えば Unicode 10302(16)
uuuuu=00001(2)
xxxxxxxxxxxxxxxx=0000001100000010(2)
wwww=0000(2)
110110wwwwxxxxxx=1101100000000000(2)=D800(16)
110111xxxxxxxxxx=1101111100000010(2)=DF02(16)
となる。

もっと計算しやすい Surrogate pair の形式は考えられたろうに...