システム開発での文字関係の整理


システムと文字関係の用語は、レイヤーを意識して、
文脈に合わせて適切に使用、理解しないといけないと思います。
主に日本のシステム開発では、字形認識相違、文字化けが懸念シナリオだと思っています。

文字コード
　→文字　：言語、概念の可視化。一定範囲の国家、地域で通用する有形の情報。
　→コード：符号化、数値化及びその結果。
特にこの言葉は何を意味しているのか、要注意だと思っています。

以下に幾つかの整理を行いました。

# 文字関係の概念の発展

```
1. 概念としての言葉がある
   ├─ 言語の誕生（話し言葉）
   ├─ 概念の伝達手段としての発達（象形文字、記号）

↓
2. 文字の概念が生まれる
   ├─ 文字集合（Character Set）
   │   ├─ 例：楔形文字、漢字、アルファベット
   │   ├─ 文字の分類（表音文字・表意文字）
   │   ├─ 文字の単位（モーラ、音素、音節）
   ├─ 具体例：
       ├─ ASCII（英字）
       ├─ JIS X 0208（日本語）
       ├─ Unicode（多言語対応）

↓
3. 文字の形が生まれる
   ├─ グリフ（Glyph）
   │   ├─ 文字の見た目（手書き、印刷、デジタル）
   │   ├─ 異体字（形の違う同じ文字）
   │   ├─ 絵文字（Pictograph）
   ├─ 具体例：
       ├─ 明朝体、ゴシック体
       ├─ 楷書、草書
       ├─ 絵文字（😀 🏠 ✈️）

↓
4. 文字の一覧化とIDが考えられる
   ├─ コードポイント（Code Point）
   │   ├─ 各文字に一意の番号を付与
   │   ├─ 例：
   │   │   ├─ "A" → U+0041
   │   │   ├─ "あ" → U+3042
   │   │   ├─ "𩸽"（ホッケの異字体） → U+29E3D
   ├─ 文字の検索や識別が可能になる

↓
5. 文字のシステム表示用コード化が考えられる
   ├─ 文字符号化方式（Encoding）
   │   ├─ 文字のデータ化
   │   ├─ 可変長エンコーディング（UTF-8）
   │   ├─ 固定長エンコーディング（UTF-32）
   │   ├─ 1バイト文字、2バイト文字、3バイト文字
   ├─ 具体例：
       ├─ ASCII（7ビット）
       ├─ Shift_JIS（可変長）
       ├─ UTF-8（可変長）
       ├─ UTF-16, UTF-32（固定長）

↓
6. 文字のシステム用の字形セットが考えられる
   ├─ フォント（Font）
   │   ├─ コンピュータ上で文字を描画
   │   ├─ ビットマップフォント、アウトラインフォント
   │   ├─ TrueType, OpenType
   ├─ 具体例：
       ├─ WindowsのMS明朝、MSゴシック
       ├─ macOSのヒラギノフォント
       ├─ GoogleのNotoフォント（多言語対応）

↓
7. 文字の使い方が拡張される
   ├─ 異字体の制御（IVS: Ideographic Variation Sequence）
   │   ├─ Unicodeで異字体を管理
   │   ├─ 日本語のJIS2004とJIS90の違い
   ├─ 絵文字の統一と追加
   │   ├─ Unicode 6.0で正式な絵文字セットが定義
   │   ├─ 企業ごとのデザイン違い（Apple, Google, Microsoft）
   ├─ 外字（ユーザー独自の文字）
   │   ├─ システムや業務で独自定義
   │   ├─ Windowsの外字領域（私用領域）

```

# 文字コード関連用語の樹形図
集合でもありコード化でもある、という用語もある。

```
文字とシステム
├── 文字コード
│   ├── ASCII
│   ├── JIS
│   │   ├── JIS X 0201
│   │   ├── JIS X 0208
│   │   ├── JIS X 0212
│   │   └── JIS X 0213 (JIS2004)
│   ├── Shift_JIS
│   ├── MS932 (Windows-31J)
│   ├── EUC-JP
│   ├── Unicode
│   │   ├── UTF-8
│   │   ├── UTF-16
│   │   └── UTF-32
│   ├── 中国語
│   │   ├── GB2312
│   │   ├── Big5
│   │   └── GB18030
│   ├── 韓国語
│   │   └── KS X 1001
│   ├── ISO-8859
│   └── Windows-1252
├── 文字集合
│   ├── JIS 第一水準
│   ├── JIS 第二水準
│   ├── JIS8
│   ├── コードポイント
│   └── キャラセット
├── 文字符号化方式
│   ├── 1バイト文字
│   ├── 2バイト文字
│   ├── 3バイト文字
│   └── エンコーディング方式
├── フォントとグリフ
│   ├── グリフ
│   ├── フォント
│   └── 外字
└── 異字体と文字変化
    ├── 異字体
    ├── JIS2004
    └── Unicode IVS

```

# 文字コードの歴史年表

| 年 | 出来事 | 情報源 |
|----|--------|--------|
| **1963年** | ASCII（7ビット）の標準化 | [ASCIIの誕生](http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/ASCII.html) |
| **1964年** | IBMがSystem/360と共にEBCDICを発表 | [文字コード - Wikipedia](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89) |
| **1978年** | JIS C 6226-1978（後のJIS X 0208）制定 | [JIS漢字コードの変遷](https://sound.jp/mtnest/k/JIS-history.htm) |
| **1983年** | JIS X 0208-1983 改訂 | [JIS漢字コードの変遷](https://sound.jp/mtnest/k/JIS-history.htm) |
| **1987年** | ISO/IEC 8859-1（ラテン1）標準化 | [文字コード - Wikipedia](https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89) |
| **1990年** | Unicode 1.0 草案発表 | [Unicodeとは？ その歴史と進化](https://www.buildinsider.net/language/csharpunicode/01) |
| **1991年** | Unicode 1.0 正式発表 | [Unicodeとは？ その歴史と進化](https://www.buildinsider.net/language/csharpunicode/01) |
| **1992年** | UTF-8 の提案 | [UTF-8 - Wikipedia](https://zh.wikipedia.org/wiki/UTF-8) |
| **1993年** | JIS X 0212 制定 | [文字コード年表 - 漢字情報研究センター](http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/chronology.html) |
| **2000年** | JIS X 0213 制定 | [JIS漢字コードの変遷](https://sound.jp/mtnest/k/JIS-history.htm) |
| **2010年** | Unicode 6.0 公開（絵文字の追加） | [Unicode - Wikipedia](https://zh.wikipedia.org/wiki/Unicode) |
| **2017年** | Unicode 10.0 公開（漢字の拡張） | [Unicode - Wikipedia](https://zh.wikipedia.org/wiki/Unicode) |


# 文字関係のフローいくつか

```mermaid
graph TD
  subgraph 文字コード
    A1(ASCII) -->|拡張| A2(ISO-8859)
    A1 -->|派生| A3(JIS X 0201、0208)
    A3 -->|統合| A4(Shift_JIS)
    A4 -->|拡張| A5(MS932)
    A2 -->|Unicode化| A6(Unicode)
    A6 -->|エンコーディング| A7(UTF-8)
    A6 -->|エンコーディング| A8(UTF-16)
    A6 -->|エンコーディング| A9(UTF-32)
  end

  subgraph フォントとグリフ
    B1(グリフ) -->|組み合わせ| B2(フォント)
    B2 -->|描画| B3(システム画面)
    B4(外字) -->|追加| B2
  end

  subgraph 異字体と文字変化
    C1(異字体) -->|区別| C2(JIS 2004)
    C2 -->|包含| C3(JIS X 0213)
  end

```

# 文字化けの基本構造
保存と表示のエンコード、デコード非対称による。

| ステップ | 正常な流れ | 文字化けが発生するケース |
|----------|----------|------------------|
| ① 文字入力（キーボード操作） | 「あ」 (U+3042) を入力 | 「あ」 (U+3042) を入力 |
| ② エンコード（メモ帳保存） | UTF-8 → `E3 81 82` | Shift_JIS → `82 A0` |
| ③ バイナリ保存 | `E3 81 82` (UTF-8のバイト列) | `82 A0` (Shift_JISのバイト列) |
| ④ デコード（ブラウザ描画中） | UTF-8 → 「あ」 | **UTF-8で誤解釈 → `E3 81 82` を再解釈 → `ã‚`** |
| ⑤ 画面表示（ブラウザ描画結果） | 正しく「あ」が表示される | 文字化け（`ã‚` のような変な文字） |

---

# データライフサイクル

```mermaid
graph TD
  A[入力] -->|キーボード/IME| B[エンコード]
  B -->|UTF-8,Shift_JIS| C[内部処理]
  C -->|正規化/変換| D[データ保存]
  D -->|DB,ファイル| E[通信]
  E -->|HTTP/JSON| F[表示]
  F -->|フォント/UI| G[ユーザー]
```
1. **物理層（入力）**
   - キーボード、音声認識、OCR
   - IME（日本語入力システム）
2. **エンコード層**
   - 文字コードの変換（UTF-8, Shift_JIS, EUC-JP）
   - コードポイントとバイト列の変換
3. **アプリケーション層（処理）**
   - 文字列操作（検索、正規化、変換）
   - テキスト解析（形態素解析、スペルチェック）
4. **保存層**
   - データベース（MySQL, PostgreSQLの文字セット）
   - ファイル（JSON, XML, CSV, Markdown）
5. **通信層**
   - API、HTTP（Content-Type: text/html; charset=UTF-8）
   - メールの文字コード（MIMEエンコーディング）
6. **表示層**
   - UIのフォント・グリフ管理
   - 異体字や絵文字のレンダリング

# エンディアンの整理
保存と表示の非対称と言えばこういう話も。

```mermaid

graph TD
  A[リトルエンディアン] -->|加算の効率が良い| B[CPUの算術演算]
  A -->|メモリアドレスの増加方向と一致| C[スタックの動作に有利]
  D[ビッグエンディアン] -->|人間の読みに近い| E[データダンプやデバッグに有利]
  D -->|ネットワークと互換性がある| F[通信プロトコルに適用]


```
- ビッグエンディアン (Big Endian)：
  - MSB（Most Significant Byte：最上位バイト）を先頭に格納
  - 人間の読みに近い（メモリダンプでそのまま数値が見える）
  - ネットワークプロトコル（IP, TCP, UDP） は Big Endian が標準
  - IBM PowerPC, Sparc, 一部の組み込み機器
- リトルエンディアン (Little Endian)：
  - LSB（Least Significant Byte：最下位バイト）を先頭に格納
  - CPUの算術演算に有利（アドレスの低い方から足し算が可能）
  - Intel系CPUを使った一部のネットワーク機器ではエンディアン変換が必要
  -  x86 (Intel, AMD), ARM（モード切替可能）

### **エンディアン問題の流れ（データ保存と読み込み）**
| ステップ | UNIX（ビッグエンディアン） | Windows（リトルエンディアン） |
|----------|---------------------|----------------------|
| **1. 数値を保存** | `0x12345678` をメモリに保存 | `0x12345678` をメモリに保存 |
| **2. メモリのバイト配置** | `12 34 56 78` | `78 56 34 12` |
| **3. データをファイルに書き出し** | `12 34 56 78` の順で保存 | `78 56 34 12` の順で保存 |
| **4. 他のOSで読み込み** | **Windowsが `12 34 56 78` をそのまま読む** → **誤った数値に！** | **UNIXが `78 56 34 12` をそのまま読む** → **誤った数値に！** |
| **5. 正しく読み込むには？** | **エンディアン変換が必要** (`htonl()` など) | **エンディアン変換が必要** (`ntohl()` など) |

# 有名な文字関係の攻撃

https://ascii.jp/elem/000/000/633/633035/

```mermaid
graph TD
  A[攻撃者がファイル名やコードに RLO（U+202E） を埋め込む] -->|システムがUnicodeの双方向制御文字を処理| B[文字の並び順が反転]
  B -->|ファイル拡張子やコードが見かけと異なる| C[ユーザーが誤認]
  C -->|誤認したファイルを開く| D[マルウェア実行/XSS/フィッシング発生]

```