システムと文字関係の用語は、レイヤーを意識して、
文脈に合わせて適切に使用、理解しないといけないと思います。
主に日本のシステム開発では、字形認識相違、文字化けが懸念シナリオだと思っています。
文字コード
→文字 :言語、概念の可視化。一定範囲の国家、地域で通用する有形の情報。
→コード:符号化、数値化及びその結果。
特にこの言葉は何を意味しているのか、要注意だと思っています。
以下に幾つかの整理を行いました。
文字関係の概念の発展
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の誕生 |
1964年 | IBMがSystem/360と共にEBCDICを発表 | 文字コード - Wikipedia |
1978年 | JIS C 6226-1978(後のJIS X 0208)制定 | JIS漢字コードの変遷 |
1983年 | JIS X 0208-1983 改訂 | JIS漢字コードの変遷 |
1987年 | ISO/IEC 8859-1(ラテン1)標準化 | 文字コード - Wikipedia |
1990年 | Unicode 1.0 草案発表 | Unicodeとは? その歴史と進化 |
1991年 | Unicode 1.0 正式発表 | Unicodeとは? その歴史と進化 |
1992年 | UTF-8 の提案 | UTF-8 - Wikipedia |
1993年 | JIS X 0212 制定 | 文字コード年表 - 漢字情報研究センター |
2000年 | JIS X 0213 制定 | JIS漢字コードの変遷 |
2010年 | Unicode 6.0 公開(絵文字の追加) | Unicode - Wikipedia |
2017年 | Unicode 10.0 公開(漢字の拡張) | Unicode - Wikipedia |
文字関係のフローいくつか
文字化けの基本構造
保存と表示のエンコード、デコード非対称による。
ステップ | 正常な流れ | 文字化けが発生するケース |
---|---|---|
① 文字入力(キーボード操作) | 「あ」 (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 を再解釈 → ã‚ |
⑤ 画面表示(ブラウザ描画結果) | 正しく「あ」が表示される | 文字化け(ã‚ のような変な文字) |
データライフサイクル
-
物理層(入力)
- キーボード、音声認識、OCR
- IME(日本語入力システム)
-
エンコード層
- 文字コードの変換(UTF-8, Shift_JIS, EUC-JP)
- コードポイントとバイト列の変換
-
アプリケーション層(処理)
- 文字列操作(検索、正規化、変換)
- テキスト解析(形態素解析、スペルチェック)
-
保存層
- データベース(MySQL, PostgreSQLの文字セット)
- ファイル(JSON, XML, CSV, Markdown)
-
通信層
- API、HTTP(Content-Type: text/html; charset=UTF-8)
- メールの文字コード(MIMEエンコーディング)
-
表示層
- UIのフォント・グリフ管理
- 異体字や絵文字のレンダリング
エンディアンの整理
保存と表示の非対称と言えばこういう話も。
- ビッグエンディアン (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() など) |
有名な文字関係の攻撃