💭

文字コードはUTF-8を使おう!

2022/04/09に公開

結論:Unicodeを使いましょう!!!!!

文字コードって何?なぜ必要?

まず、コンピュータは0と1しか理解しません。整数も実数も文字列も全て、コンピュータ内部では「0と1の並び」として保存されます。

例えば、、、

  • 画像の場合は、各ピクセルのRGBの値を保存する
  • 音の場合は、各時間の空気圧を数値として保存する

文字コードは「文字列を0と1の並びで表現する方法」です!
例えば、、こんな感じ、、

  • 'A' -> 0001
  • 'B' -> 0010

この「文字」と「コード」の対応表を「文字コード」と言います。

良い文字コードの満たすべき性質

文字コードを設計する上で「絶対に必要な性質」「あったら嬉しい性質」を考えていきます!

絶対に必要な性質

1. 元の文字が復元できる

文字コードでエンコード(文字を0,1の列に変換すること)されたデータから元の文字列がデコード(0,1の列から元の文字を復元すること)ができる

「当たり前じゃん」と思いますが、実は結構難しいです。
たとえば、'A' -> 1, 'B' -> 10, 'C' -> 11という文字コードを考えると、1110というデータがAABなのかCBかわからないですよね。つまり、エンコードはできるけど、でコードができない文字コードになってしまっています。

あったら嬉しい性質

1. たくさんの文字が表せる

英語アルファベットしか表せない文字コードは、漢字が必須な日本では使えないですよね。
表現できる文字が少ない文字コードは世界的に広めることができなくて、廃れてしまいます。
逆に、Unicodeという文字コードは全世界の文字を扱えるように設計されて、現状文字コードのスタンダートになってます。

2. 効率が良い

同じ1万文字のテキストファイルを保存するときに、10kBで済む文字コードと50kB必要な文字コードでは、10kBで済む文字コードを使いたいですよね。同じ文字列を表すのであれば、できるだけ少ない容量で表現できると嬉しいです。

3. 「文字列演算」が簡単にできる

メールアドレスの正規化などで、小文字(abc)を大文字(ABC)や、ひらがなをカタカナにするといった文字列操作は頻繁に行います。
シンプルには、小文字と大文字を対応付ける表を事前に作っておいて、その表を見ながら文字コードを入れ替えていくという操作になりますが、文字ごとに表を参照しないといけなくて非効率です。
ASCIIでは工夫されていて、8bitsのうち1bitを反転すると大文字小文字変換ができるようになってます。

4. 文字列の長さが簡単にわかる

プログラムの中で文字列がどれくらいの長さか?を計算することはたくさんあります。なので、長さの計算はできるだけ高速に行いたいわけです。
ASCIIではこれが実現できています。1文字が1byteで表現されるのでデータのbyte数を見れば、それがそのまま文字列の長さになります。しかし、UTF-8やShift-JISでは一文字の長さが文字によって異なるので、文字列のデータを読み込まないと文字列の長さがが計算できないです。

有名な文字コード

上であげた性質のうち、なのを重要視し、何を諦めるかでいろんな文字コードが生まれてきました。ここでは有名な文字コードをいくつか紹介します。

ASCII (American Standard Code for Information Interchange)

名前の通りアメリカ発で、アルファベットに特化した文字コードです。
「文字コードの元祖」と言って良いくらい古い文字コードで、その他の文字コードはASCIIから派生してきたものがほとんどなはずです。

表現できる文字は、アルファベットの大文字・小文字、数字、.,などの記号、「改行」などの制御記号などの128文字(2^7)です。
一文字を表現するのに7bit(実際は1bitをパリティなどに使い、8bit=1byteとする)使うので、文字列の長さを測ったり、n番目の文字に移動するのが簡単になるように設計されてます。

その分「たくさんの文字が表せる」は実現できていなく、英語を表すのでギリギリです。
英語にも比較的出てくるアクセント記号なども表現できないので、漢字はもってのほかですね。

Shift-JIS

ASCIIでは日本語が表現できないので、日本語用に作られた文字コードです。

表現できる文字は、ASCIIの文字全てに加えて、ひらがな、カタカナ、漢字、キリル文字などが表現可能です。
ASCIIのほぼ拡張になっていて、ASCII文字は1byteで表現し、それ以外を2byteで表現する方式です。
文字によって、byte数が変わるので、「文字列の長さが簡単にわかる」や「n文字目に遷移できる」は達成できてないです。

また、ASCII文字以外の部分で「文字が割り当てられていない箇所」があるのが特徴です。この空いたスペースを有効活用しようと、いろんな携帯会社が勝手にこの部分に絵文字などをを当てはめていきました。
ガラケー時代に、キャリアを跨いでメールを送ると絵文字が文字化けするのはこれが原因です。

Unicode (UTF-8)

Shift-JISのような各国特有の文字コードが乱立し、文字化けが起こりまくったので統一するために作られた文字コードです

1〜4byteで一つの文字を表現する形式で、1,112,064文字が表現できます。世界中の言語・絵文字・記号が表現できるようになっていて、高頻度で新しい文字が追加されています。
中でも、出現頻度の高いアルファベットは1byteで表現できるように設計されているので、全体のデータ量はあまり増えないように設計されています。

しかし、文字によってデータサイズが変わるので、文字列の長さを判定したり、n文字目に移動するためには、文字列全体を読み込む必要があるという欠点もあります。

特殊な理由がない限りUTF-8を使おう

文字コードは統一されていることが重要です。ファイルがShift-JISで書かれているのに読み込むソフトウェアがUTF-8と認識してしまうと、文字化けが起こります。さらに一つのシステム内で複数の文字コードが混ざってしまうと、境界部分で文字コードの変換が必要になったり、、、

現代では、データが全てアルファベットや日本語文字だけで完結することは少ないですし、ぜひUTF-8に統一して、文字化けの起きないソフトウェアを作っていきましょう!

Discussion