文字コードって?
コンピュータ上で、文字の情報を記録する方法には複数ある。
「手書き」と「キーボード入力」といった意味ではなく、キーボードでExcelなりWebサイトなりに文字を入力したときにそれを記録する方法が複数あるのだ。
xlsxファイルのような作るのはExcel・開くのもExcelと決まっているファイルでは、文字コードはある1種類に決められており意識する事はない。
しかし、txtファイルなどでは、ファイル自体にはどの文字コードなのかの情報が含まれていない。例えば、作ったときに「UTF-8」という文字コードを選び、開くときに「Shift_JIS」を選ぶと「文字化け」が起きる。
文字コードは2つの部分からなる
コンピュータで文字を扱うには次の2つを決めなければならない。それが文字コード:
- ①取り扱う文字を決め、文字にコードポイントという番号を割り振る(文字集合)
- ②コードポイントの列をコンピュータの基本単位であるバイトで表現する方法を決める(符号化方式)
大体の文字コードの規格では①②がセットになっていて、混同されだが、本当は違うもの。
Unicode(UTF-8、UTF-32、UTF-16、UTF-8 with BOMなど)
Unicodeは世界のあらゆる文字を扱える世界共通の文字コードを作ろうという一大プロジェクト。
Unicodeが定める文字集合は2019年5月7日現在で13万7929文字を収録しコードポイントを割り振っている。将来、最大111万4112文字まで収録できるよう、番号を確保している。つまり、コードポイントは0 ~ 1114111の範囲の数値になる。
1バイトは0〜255の数値しか表せないので、Unicodeの符号化方式は複数のバイトを組み合わせるものにならざるを得ない。Unicodeでは複数の符号化方式を定めている:
- UTF-8: 従来の文字コード(ASCII)と互換性があるなどイケているので今の主流
- UTF-32: 全ての文字を一律4バイトで表す。プログラム的に扱いやすいが、データ量が従来の文字コードより大きくなってしまうのが欠点
- UTF-16: 全ての文字を一律2バイトで表す。Unicodeの収録文字数が少ない頃に2バイト(256×256=65536文字扱える)で十分だろうと思って作った。十分なわけがなかった
- 他にも符号化方式が定義されている。UTF-32、UTF-16にも変種がある
また、「UTF-8 with BOM」は符号化方式ではないが、世間では便宜上符号化方式の1つとして扱っている。UTF-8で符号化したバイト列の先頭に、通常は無視される特殊な3バイト(BOM)を追加する。プログラムはこの先頭3バイトがあれば、そのデータがUnicode文字集合&UTF-8で符号化されていると推定できる。この「UTF-8で符号化して先頭3バイトをつけるやつ」を「UTF-8 with BOM」と呼ぶ。しかし、プログラムによっては「全体はUTF-8なのに、先頭に変な3バイトが入ってる」としか認識しないものもあるので困ったものだ。
なお、世間では「このテキストファイルはUnicodeだ」のように言う人がいる。言葉のマナーをどうこういう気はないのだが、実際問題、Unicodeには符号化方式が複数あるので「Unicode」だけだと、UTF-8、UTF-32、UTF-16 etc... を区別できないことがある。しかし、世間で流通しているファイルはUTF-8が圧倒的多数なので、彼の人は「Unicode=UTF-8」の意味で使っていることが多いだろう。
絵文字
Unicodeの文字集合には「🌝」「🐕️」などの絵文字も収録されている。アルファベットや漢字は画面上で黒く表示され、絵文字はカラフルに表示されるが、それは表示する側のソフトウェアが気を利かせているだけで、UTF-8などでエンコードするときはほぼ同じように扱われる。
Shift_JISなどの旧来の文字コードには絵文字が収録されておらず、絵文字はUnicodeの売りの一つだった。
ASCII
ASCIIは英語用の文字コード。文字集合はアルファベットと記号のみ。
しかし、ほとんどの文字コードはASCIIに別の文字(漢字など)を追加する形で作っているので、ASCIIに収録されている文字はどこでも問題なく使えるはず。
ASCIIにヨーロッパ各国の文字(ÅとかÆとか)を加えた文字コードがある。
ASCIIでは全ての文字が1文字=1バイトで符号化されるので分かりやすい。しかし、そのせいで「欧米人がこの世の全ての文字は1バイトだと思ってプログラムを書き、他の文字コードを扱ったときにバグる」といったことがしばしばあった(今もある?)。
EUC-JP
EUC-JPは日本語用の文字コード。
文字集合はUnicodeより小さい。
符号化方式は、ASCIIの範囲の文字はASCIIと同様1バイト、漢字などの追加の文字は2バイトで符号化する。
昔のUnixやLinuxでよく使われた。
Shift_JIS
Shift_JISは日本語用の文字コード。EUC-JP同様、文字集合はUnicodeより小さく、符号化方式も、ASCIIの範囲の文字は1バイト、漢字などの追加の文字は2バイトで符号化する。
WindowsやMicrosoft Excelで使われている。
Shift_JISは2つの意味でプログラマーの頭痛の種。
1つは、1文字=1バイトだと思い込んで書いたプログラムが、Shift_JISのデータで特に重大バグを起こすこと。
もう1つは、Shift_JISは規格として定まっているのだが、Windows業界ではShift_JISに独自の文字を文字集合に追加したものを「Shift_JIS」と称していること。そのため、Windows方面から渡ってきた「Shift_JISのファイル」を馬鹿正直にShift_JISとして取り扱うと「文字集合に含まれない謎のコードポイントがある」ことになってしまう。「本来のShift_JISではなくWindowsでいうところのShift_JISである」と明示したいときは「Windows-31J」または「cp932」と呼ぶべきである。
文字コードとOSの関係
本来、文字コードとOS(Windows、Mac、Android、iOS)は無関係だ。
どのOSであっても、Shift_JISのファイルを読み込むプログラムを作ることができる。他の文字コードのプログラムも作ることができる。
しかし、OSと文字コードに全く対応関係が無いわけではない。
例えばOSはファイルの名前を特定の文字コードで処理しているので、その文字コードの文字集合に含まれない文字はファイル名に使えない。
また、OSに標準で付属するプログラム(『メモ帳』など)が特定の文字コードしか扱えないことがある。そのため、あるOSの標準プログラム(文字コードA固定)で作ったファイルを別のOSの標準プログラム(文字コードB固定)で開こうとすると文字化けする。