プロジェクト

全般

プロフィール

文字コード » 履歴 » バージョン 1

kanata, 2025/04/13 15:35

1 1 kanata
# 文字コード
2
3
なんか仕事でやりそうだったので、この際カオスだった文字コード云々を整理してみる。
4
5
{{rawhtml(<canvas id="map"></canvas><script src="/javascripts/pagemap.min.js"></script><script>pagemap(document.querySelector("#map"));</script>)}}
6
7
{{toc}}
8
9
# 概要
10
11
## 文字セットと符号化方式
12
13
まず、文字セット(文字集合)と符号化方式という概念を理解することが必要。
14
15
### 文字セットとは
16
17
アルファベットや記号はもちろん、漢字やひらがな、ハングルやヘブライ文字など、世界中で使われている文字を集めたもの。
18
19
Unicodeは文字集合です。
20
21
Unicodeは便宜上、Unicodeスカラ値(16進数にU+をつけて U+0000~U+20FFFF で表現)という値で文字を管理しています。
22
Unicodeスカラ値はコードポイントという呼ばれ方をすることもあります。厳密には意味が違いますが、ここでは同じものだと思っておけば大過ありません。
23
24
### 符号化方式とは
25
26
文字セットで定義されている一つ一つの文字を、どのように符号化するかという文字符号化方式(エンコーディング)です。
27
28
Unicodeという一つの文字集合に対して、異なる文字符号化方式UTF-8、UTF-16が存在し、符号化した結果も異なります。
29
30
## UTF-8とUTF-16の符号化方式の実装例
31
32
| Unicodeスカラ値 | 文字 | 説明 | UTF-8 | UTF-16 |
33
|-----------------|------|------|-------|--------|
34
| U+0041 | A | ラテン文字 | 41 | 0041
35
| U+0061 | a | ラテン文字 | 61 | 0061
36
| U+00E8 | è | ラテン文字 | C3 A8 | 00E8
37
|  U+042F | Я | キリル文字(ロシア) | D0 AF | 042F
38
| U+05D0 | א | ヘブライ文字 | D7 90 | 05D0
39
| U+0905 | अ | デーヴァナーガリ文字 | E0 A4 85 | 0905
40
| U+0E04 | ค | タイ文字 | E0 B8 84 | 0E04
41
| U+2162 | Ⅲ | ローマ数字 | E2 85 A2 | 2162
42
| U+3042 | あ | ひらがな | E3 81 82 | 3042
43
| U+4E9C | 亜 | 漢字(あ) | E4 BA 9C | 4E9C
44
| U+D558 | 하 | ハングル | ED 95 98 | D558
45
| U+103A0 | 𐎠*1 | 楔形文字 | F0 90 8E A0 | D800 DFA0
46
| U+2000B | 𠀋 | 漢字(じょう) | F0 A0 80 8B | D840 DC0B
47
| U+20BB7 | 𠮷 | 漢字(よし) | F0 A0 AE B7 | D842 DFB7
48
| U+29E3D | 𩸽 | 漢字(ほっけ) | F0 A9 B8 BD | D867 DE3D
49
50
*1…現状どのブラウザでも表示できないっぽい。フォントが用意されていないのかも?
51
52
## 文字セットと符号化方式の関係
53
54
ここ超重要。
55
56
```
57
┏文字セット(JIS) ━━━━━━━━━━┓              ┏文字セット(Unicode) ━━━━━━━━┓
58
┃                                    ┃              ┃                                    ┃
59
┃┌JIS X 0213(JIS2004) ──────┐┃              ┃┌UCS4──────────────┐┃
60
┃│ 第三水準                       │┃              ┃│ 4byteで表現できる文字の範囲    │┃
61
┃│ 第四水準                       │┃ どんな文字を ┃│                                │┃
62
┃│ +10文字                        │┃ 取り込むか   ┃│                                │┃
63
┃│                                │┃ インプットに ┃│                                │┃
64
┃│┌JIS X 208(JIS90)─┐          │┃ なってる     ┃│┌UCS2───────┐          │┃
65
┃││ 第一水準         │          │┃ →→→→→→ ┃││2byteで表現できる │          │┃
66
┃││ 第二水準         │          │┃              ┃││文字の範囲        │          │┃
67
┃││                  │          │┃              ┃││                  │          │┃
68
┃│└─────────┘          │┃              ┃│└─────────┘          │┃
69
┃└────────────────┘┃              ┃└────────────────┘┃
70
┃                                    ┃              ┃                                    ┃
71
┃ ※文字毎にJISコードっていう番号が  ┃              ┃ ※文字毎にUnicodeスカラ値っていう  ┃
72
┃   振られているけど、現在ではあまり ┃              ┃   番号が振られているけど、そのまま ┃
73
┃   使われない。                     ┃              ┃   使わない。                   ┃
74
┗━━━━━━━━━━━━━━━━━━┛              ┗━━━━━━━━━━━━━━━━━━┛
75
  ↓JISコードを1bitシフト ↓JISコードに0x8080を加算     ↓スカラ値をなんか  ↓スカラ値をなんか
76
  ↓                      ↓                            ↓いい感じに計算    ↓いい感じに計算
77
┌Shift JIS ──┐┌EUC ─────┐          ┌UTF-16───────┐┌UTF-8 ───────┐
78
│JIS X 208まで ││              │          │基本           2byte││ASCII          1byte│
79
└───────┘└───────┘          │サロゲート文字 4byte││ギリシャ文字等 2byte│
80
  ↓                                          └──────────┘│ほとんどの漢字 3byte│
81
  ↓Microsoftが独自拡張                                               │JIS X 0213相当 4byte│
82
  ↓                                                                  └──────────┘
83
┌CP932 ────────────┐
84
│拡張文字が詰め込まれている    │
85
│ - JIS X 0201(半角カナ)       │
86
│ - NEC拡張文字(①とか)        │
87
│ - IBM拡張文字                │
88
│ - NEC選定IBM拡張文字         │
89
│                              │
90
│呼び方違うだけで同じものがある│
91
│MS932       ← Javaでの呼び方 │
92
│Windows-31J ← IANAでの呼び方 │
93
└───────────────┘
94
```
95
96
## JIS X 0213(JIS2004)とUTF-16(サロゲート文字)とUTF-8(4Byte文字)の微妙な関係
97
98
### UTF-16(サロゲート文字)
99
100
サロゲート文字に、JIS X 0213(JIS2004)の文字が、 **だいたい** 入っている。
101
ただ、2Byte範囲の方にも入っているので、完全に対応していない。
102
103
### UTF-8(4Byte文字)
104
105
UTF-8(4Byte文字)に、JIS X 0213(JIS2004)の文字が、 **だいたい** 入っている。らしい。
106
(本当かどうか未確認)
107
108
## みんなの混乱を招く、混同している所
109
110
### Shift JIS と CP932の混同
111
112
* Windowsは、ANSIと呼んたりする。それCP932や。。
113
* CP932をShift JISと呼んでるソフトやOSがあるが、厳密には間違っている。
114
115
### 同じものなのに呼称が異なる
116
117
* CP932,MS932,Windows-31J 同じもんや・・・しかも、これらが Shift JISと混同される
118
119
### UnicodeとUTF-16・UTF-8の混同
120
121
Unicodeは、文字セットであり、文字コードでは無いが、一部のソフトやOSで混同している。
122
123
* Windowsでは、Unicodeと言えば、UTF-16を指している
124
125
### サロゲートペア・サロゲート文字の混同
126
127
本来は、UTF-16の2byte範囲で表現しきれない文字に対して、名付けられた名称である。
128
が、UTF-8の4Byte文字に対して、サロゲート文字と誤って呼ぶケースが多い。
129
130
## EBCDIC+JEF
131
132
蛇足だが、レガシーシステムの文字コードはこんな感じ。
133
134
```
135
┌EBCDIC──┐ ┌JIS X 028(JIS90)──────────┐
136
│ASCIIとは │ │そのままのJISコード値を使うが、     │
137
│別の独自の│+│どこから漢字かが、判らないので      │
138
│文字コード│ │KI:漢字イン                         │
139
│          │ │KO:漢字アウト                       │
140
│          │ │と呼ばれる制御コードで囲む必要がある│
141
└─────┘ └──────────────────┘
142
```
143
144
hidekatsu-izuno 日々の記録 -  JEF4J をリリースしてみた。あるいは、メインフレームの文字コードの話。
145
http://hidekatsu-izuno.hatenablog.com/entry/2018/01/14/140124
146
147
# UTF-8の4Byte文字(または、サロゲートペア)は、何が面倒なのか
148
149
## UTF-8から、CP932(または、Shift JIS)への変換ができない
150
151
UTF-8の4Byteは、すべからくJISの第三水準・第四水準文字であるから、CP932(または、Shift JIS)には変換できない。
152
153
Windowsは「JIS第3・第4水準はUnicodeで対応する(Shift JISには追加しない)」というスタンスらしい。
154
155
156
157
## DB保存ができない
158
159
MySQLもOracle Database同様にUTF-8で文字を保存できる。ところが、4Byte文字を想定していないために、4バイトとなる文字を格納できない。
160
161
162
163
## プログラミングが面倒
164
165
byteとして扱った瞬間から、文字数のカウントやら、どれがサロゲート文字なのか判定が必要やら、考慮しなきゃいけないことが増えまくる。
166
167
168
## 容量の見積もりが面倒
169
170
実際は、DBの容量見積もりとかも含めて、もっと大きなスケールになると思うけど。
171
172
100文字記録されるファイルが100個あるとするじゃん?
173
1文字2byteだったら、
174
175
2byte * 100文字 * 100ファイル ≒ 20kbyte じゃん?
176
177
でも、UTF-8だと、1文字1byte~4byteじゃん?
178
しょうがないから、最大値で見積もるじゃん?
179
180
4byte * 100文字 * 100ファイル ≒ 40kbyte で倍になるじゃん?
181
182
でも、サロゲート文字で埋め尽くされることは無いだろうから、容量の無駄じゃん?
183
「容量の無駄なんでちょっと減らしときますね\^\^」とか、お客さんに説明できないじゃん?
184
185
# 文字コードにおける諸所のトラブル原因
186
187
## 波ダッシュ問題
188
189
[まとめ中](https://www.google.co.jp/search?hl=ja&as_qdr=y15&lr=lang_ja&num=100&q=%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E5%95%8F%E9%A1%8C&gws_rd=ssl#spf=1)
190
191
Unicodeの字形の登録ミスに起因して、以下の状態になっています。
192
193
* 波ダッシュ 〜
194
 * WAVE DASH(ユニコードポイント : U+301C)
195
196
* 全角チルダ ~
197
 * FULLWIDTH TILDE(ユニコードポイント : U+FF5E)
198
 * Shift JIS には存在しない
199
200
同じ字形に見えますね。Windowsなどでは波ダッシュの代用として全角チルダが不適切に使われるので混乱の元となっています。Macで入力した"〜"とWindowsで入力した"~"は違うものとして扱われます。仮にパスワードや、パスワードを忘れた際の合言葉に使っていた場合「あれ~MacではログインできるのにWindowsではログインできないな~」ということになります。
201
202
203
## 寿司ビール問題
204
205
[まとめ中](https://www.google.co.jp/search?hl=ja&as_qdr=y15&lr=lang_ja&num=100&q=%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E5%95%8F%E9%A1%8C&gws_rd=ssl#num=100&lr=lang_ja&safe=off&hl=ja&tbs=qdr:y15,lr:lang_1ja&q=%E5%AF%BF%E5%8F%B8%E3%83%93%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C&spf=186)
206
207
🍣🍺という文字を扱えないソフトウェアがあるという所から名付けられた問題です。UTF-8において、1文字4Byteの文字を考慮しないかったことに起因した不具合でした。最近は、この不具合を抱えたソフトウェアは少なくなりました。
208
209
210
# Unicode/UTF-8のあまり知られていない仕様
211
212
## サロゲートペア
213
214
まとめ中
215
216
>𩸽
217
218
## Unicode結合文字
219
220
[まとめ中](https://www.google.co.jp/search?q=Unicode%E7%B5%90%E5%90%88%E6%96%87%E5%AD%97&safe=off&client=firefox-b&dcr=0&gbv=2&sei=yxW7WayhJYag8QXq4aKgBQ)
221
222
橋本商会 - UTF-8-MACをUTF-8に変換する
223
http://shokai.org/blog/archives/5953
224
225
### Unicode正規化 変換するワンライナー
226
227
Unicode正規化するシェル芸を作りました
228
229
python3で
230
231
```python
232
echo -n "DQⅢ①⑳海海神神㌔㍉ビデブー" | python -c "import sys,unicodedata; print(unicodedata.normalize(\"NFKC\", sys.stdin.read()));"
233
DQIII120海海神神キロミリビデブー
234
```
235
236
perlで
237
238
```perl
239
echo -n "DQⅢ①⑳海海神神㌔㍉ビデブー" | perl -e "use strict;use utf8;use Encode;use Unicode::Normalize;binmode STDIN, ':encoding(UTF-8)';binmode STDOUT, ':encoding(UTF-8)';print Unicode::Normalize::NFKC(<STDIN>);"
240
DQIII120海海神神キロミリビデブー
241
```
242
243
### 検出する方法について
244
245
{{rawhtml(<iframe src="//www.slideshare.net/slideshow/embed_code/key/DWxNqD6CmiRb5O" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/reflectresults/macos-86746675" title="macOS 濁点問題にシェル芸で挑んだ話" target="_blank">macOS 濁点問題にシェル芸で挑んだ話</a> </strong> from <strong><a href="https://www.slideshare.net/reflectresults" target="_blank">Kazuya Kohara</a></strong> </div>)}}
246
247
248
249
## 異字体セレクタ
250
251
まとめ中
252
253
254
255
256
## Article
257
258
Qiita - 絵文字を支える技術の紹介
259
https://qiita.com/nonanona/items/b148c212ba7c24942e93
260
261
絵文字がある種のUnicodeバグを世界から一掃しつつある件について
262
https://note.mu/ruiu/n/nc9d93a45c2ec
263
264
# 書籍
265
266
たかが文字コード、されど文字コード/ShiftJISerへ贈る鎮魂歌
267
https://techbookfest.org/product/5677280795820032?productVariantID=5733665126481920
268
269
ユニコード戦記 ─文字符号の国際標準化バトル
270
https://amzn.to/3redEnc
271
272
[改訂新版]プログラマのための文字コード技術入門 WEB+DB PRESS plus
273
https://amzn.to/3KY0276
274
275
# 参考
276
277
Shapecatcher(手書きの文字からUnicodeを検索)
278
https://shapecatcher.com/#
279
280
(プログラマのための)いまさら聞けない標準規格の話
281
https://www.ogis-ri.co.jp/otc/hiroba/technical/program_standards/part1.html
282
283
ㇹ゚ン゚'ㇳ̃ヴ゙ニ゙コ゚ヮヰ文̂字̠コ゚−ト゚ノ゙ㇵナ゚ㇱ(現在に至るまでの文字コードの軌跡と簡単な使い方について)
284
https://heppoko.hatenadiary.jp/entry/2018/04/28/184559
285
286
ウナのIT資格一問一答 - 文字コードやフォント、その他PC関連の読み物です。
287
http://una.soragoto.net/topics/index.html
288
289
JISから迫る文字コード入門
290
https://speakerdeck.com/todokr/jiskarapo-ruwen-zi-kodoru-men
291
292
hidekatsu-izuno 日々の記録 -  JEF4J をリリースしてみた。あるいは、メインフレームの文字コードの話。
293
http://hidekatsu-izuno.hatenablog.com/entry/2018/01/14/140124
294
295
長くて覚えやすくて複雑なパスワードとemojiの話
296
https://speakerdeck.com/ozuma/chang-kutejue-eyasukutefu-za-napasuwadotoemojifalsehua
297
298
Dive Into Python 3 第4章.文字列
299
http://diveintopython3-ja.rdy.jp/strings.html
300
301
C++標準化委員会、ついに文字とは何かを理解する: char8_t
302
https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b
303
304
アプリの国際化の舞台裏
305
https://speakerdeck.com/niw/apurifalseguo-ji-hua-falsewu-tai-li
306
307
Unicodeで絶対知っておくべきセキュリティ5つの注意(翻訳)
308
https://techracho.bpsinc.jp/hachi8833/2017_11_28/48435
309
310
UTF-8の冗長なエンコード
311
https://gihyo.jp/admin/serial/01/charcode/0004#sec2
312
313
全ての開発者が知っておくべきUnicodeについての最低限の知識
314
https://gigazine.net/news/20231005-unicode/
315
316
絵文字を支える技術について
317
https://note.com/ttuusskk/n/n1bff5d8e638c
318
319
Attacking with Character Encoding for Profit and Fun ~趣味と実益の文字コード攻撃~
320
https://www.blackhat.com/presentations/bh-jp-08/bh-jp-08-Hasegawa/BlackHat-japan-08-Hasegawa-Char-Encoding.pdf