プロジェクト

全般

プロフィール

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

kanata, 2025/05/11 13:25

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