自分にとって最高にわかりやすい「文字コードとは何か」のメモ

# はじめに
文字コード（というかUnicode）について、
会社のえらい人にはちゃめちゃに丁寧に教えていただいたので備忘録として残しておきます




追記（2024/03/29）：
偉い人が確認してくださり、
「記事の中で"異字体"と"異体字"が混在している」
とご指摘をいただいたので"異体字"に統一

["異字体"と"異体字" の違い](#追記１異字体と異体字-の違い)


# 1. 文字コードとは何か

> 文字をコンピューターで表現する際にどのようなバイト表現にするかを定めるもの

https://www.tohoho-web.com/ex/charset.html

次の２つの概念をもつ

- 符号化文字集合（CCS: Coded Characrer Set）
- 符号化方式（CES: Character Encoding Scheme）


## 符号化文字集合

文字とその文字に割り振られたID みたいなもの（code point）の集合

厳密にはID ではなく「群・面・区・点」の番号という概念なようなのですが、
帰ってこられなくだけなので深堀はしません


## 符号化方式

code point と code unit の変換規則


code unit：
code point を何バイトで表現するかの単位



最初 code point と code unit がわかっていなかったのでとても混乱したのですが、
教えていただいたサロゲートペアとか異体字セレクタ（後述）を理解する上では必須でした


# 2. Unicode とはなにか

文字コードの１つで、業界標準規格
いろんなところが好き勝手文字コード作っちゃうと互換性がなくて不便なので
みんなで同じのつかいましょうねな規格

## Unicode の符号化文字集合

- code point は 0x - 10FFFFx、約111万個ある
- しかしそのうち実際に文字が割り当てられているのは約13万個のみ
    - 私用文字に約13万個
    - 制御文字用に65個


## Unicode の符号化方式

まったく知らなかったのですが、
よく聞くUTF-8 や UTF-16 というのはこの符号化方式の名前らしいです

- UTF-8：code point を（基本的に）1byte で表現する（code unit が 1byte）
- UTF-16：code point を（基本的に）2byte で表現する（code unit が 2byte）

https://jsprimer.net/basic/string-unicode/

# 3. Unicode を扱うときの注意点（サロゲートペア・異体字セレクタ）

そもそもなぜ偉い人に文字コードの説明をしてもらう機会があったかというと、

1. ちょうど「サロゲートペア」が話題になっていた
2. 似たようなの見たことあるな？でもこれは「異体字セレクタ」だ？
3. なにがちがうんだ？？？

というつぶやきに回答をいただけたことがきっかけでした


## なぜ注意が必要なのか

サロゲートペアと異体字セレクタは両方とも１文字を表現するための方法ですが、
しかしこの方法を使って表現した文字は
「**本来１文字にもかかわらず、２文字としてコンピューターに解釈される**」ことが起こりえるので注意が必要です


## なぜそんなことが起こるのか

両方とも「**複数個の code unit を使用するため**」です

ここで code point と code unit が関係してきます


## サロゲートペア とは

サロゲートペア：
ある２つの code unit のペア


### 詳細
- Unicode の code point：0x - 10FFFFx
- UTF-16 の code unit：2byte

なので、UTF-16 ではcode point が U+10000～U+10FFFF の文字を表現できません
（厳密には「値が大きいから」にあてはまらない例外もあるらしいのですが、稀らしいので今回は無視します）


そのため、2個の code unit を使って表現します（UTF-8 ならもっと）
この code unit のペアがサロゲートペアです

https://www.tohoho-web.com/ex/charset.html#surrogates

つまり、code point が１つの文字を表現するために、２つの code unit を使用します


### サロゲートペアで表現される文字の例
- 𩸽（ほっけ）
- 𠮷（上が「士」じゃなくて「土」）

https://qiita.com/yuba/items/83a81a0de09a8d8655f1


## 異体字セレクタ とは

異体字セレクタ：
意味が同じだが表現がすこし異なる文字を表現するために使う code point
例：「竈門禰󠄀豆子」 の 「禰󠄀(部首がネ)」

### 詳細

「竈門禰󠄀豆子」 の 「禰󠄀(部首がネ)」の文字は Unicode に登録されていません
ではなんで今表示されているかというと、
「禰(部首が示)」 の異体字として表現されているからです


異体字：
意味が同じだが表現がすこし異なる文字


この異体字を表現するために使用する code point が「異体字セレクタ」です

異体字は
「基本字形の codepoint」＋「異なる字形の字形番号の異体字セレクタ」で表現されます

（「禰󠄀」の場合、「禰」のcode point + 異体字セレクタ）

https://www.tohoho-web.com/ex/charset.html#variant

つまり、code point が２つの文字を表現するために、２つの code unit を使用します


### 異体字セレクタを使用して表現される文字の例

- 禰󠄀（基本字形は「禰」）
- 葛󠄀（基本字形は「葛」）

https://qiita.com/ykami/items/d45ec72f8a5ea8b3288d


## まとめ
- サロゲートペアも異体字セレクタも１文字を表現するために使用される方法である
- しかし環境によっては２文字と解釈される
- サロゲートペアは１つのcode point を２つの code unit で表現する
- 異体字セレクタ（を使用する文字）は２つの code point を２つの code unit で表現する



# 備考

忘備録なので最初の自分の勘違いも記録としてのこしておきます
これは間違いですので見なかったことにしてください
（異字体っていってますか異体字ですね）

```
サロゲートペアと異字体セレクタ

共通点：
・世界中の文字を表すのに Unicode で想定していた 2 ** 16個 だと全然足りないので、
  2文字分で１文字を表現しようとした
・なので、気を付けないと２文字として解釈されるバグがおこる

違う点：
・サロゲートペア：未使用の Unicode の領域２つのペア、このペアで１文字を表す
・異字体セレクタ：特殊文字、既存の文字 + 異字体セレクタ で１文字を表す
```

# 追記１："異字体"と"異体字" の違い

字面がそっくりなので混合させてしまったのですが、意味が違うそうです

- 字形：文字を図形として表現したもの
- 異体字：普通につかう新字に対して、意味は同じだが字形が異なる文字（という概念）
- 異字体：異体字の字形
- 異体字には古い漢字(旧字、旧字体)や俗字などが全部含まれる

https://www.morisawa.co.jp/culture/dictionary/1924

完全に見落としていたのですが、「異字体セレクタ ではなく 異体字セレクタ でした
それすら間違えておりました

セレクタ以外でも、本ページの内容であれば
「一部異字体でも意味が通じるところもあるが、異体字に統一したほうが良い」
とお言葉をいただいたので修正しました



関係ないけどページ内リンクを張るのに詰まったので

https://qiita.com/hennin/items/7ee58dd7d7c013a23be7