文字コードとエンコーディングの仕組みを少し深掘りしていく

#143 UTF-8とかShift_JISとかUnicodeとかASCIIとか、曖昧だったそこらへんを整理する

文字コードについての理解を深める回。最近文字コードとエンコーディングについてわからず、もう少し理解が必要であったため色々と調べたことをまとめていく。文字コードについて調べていると「昨今は文字コードを気にする必要はほとんどなくなったが…」という枕詞から始まる記事を多数見受け、時代の流れ的にはあまり必要のない内容であるようにも感じるが、そういうのを知ってこそ悦に浸れることもあるのではないかと。メモリの管理を念頭において開発を行うオンプレ静的言語プログラマの持つ、イマドキとは異なる「スゴさ」に少しでも首を突っ込むことができるようになれればなと、現代の恵まれた環境でプログラムを書く駆け出しエンジニアは思う訳である。

 

目次

[toc]

 

 

そもそも文字コードとは

文字コードといえば、UTF-8とかShift-JISとかUnicodeとかASCIIとか、そこらへんが出てくる。概念を改めて確認すると、

 

サクっと一言で説明すると、コンピュータの世界における「文字に割り当てられた数字」が「文字コード(モジコード)」です。
「表現される文字のもとになっている数字」と言った方が正確ですけどね。
分かりくいので「文字に割り当てられた数字」と覚えてください。

文字コード (character code)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

 

とにかく文字コードとは、文字と機械語を関連付けている規格であることはざっくりと認識している。しかし、調べているとこれらの文字コードの規格は、単に「文字 ⇆ 機械語」の紐付けではなく、「符号化文字集合」と「文字符号化方式」という複数段階の処理が走っている。

 

文字 ⇆ 機械語への変換作業は複数段階で行われる

イメージは以下の通り。

符号化文字集合と文字符号化方式

符号化文字集合と文字符号化方式

文字「あ」のエンコーディングの流れは上の画像のようになる。「あ」にはUnicodeの規格にによって一意のコードを振られている。もちろん「あ」だけでなく全ての文字にこの一意のコードが振られている。この規格を「符号化文字集合」と呼び、UnicodeやJIS X 0208などが該当する。一方で、Unicodeによる符号化を、さらに「文字符号化方式」と呼ばれる規格によって変換する。この変換はエンコーディングとも呼ばれ、UTF-8、UTF-16、UTF-32、Shift-JIS(SJIS)、ISO-2022-JP(JIS)、EUC-JPなどよく聞く奴らがこれに該当する。UnicodeはUTF-8、UTF-16、UTF-32に対応し、JIS X 0208はShift-JIS(SJIS)、ISO-2022-JP(JIS)、EUC-JPに対応する。

基本的に現代はUTF-8だが、Microsoft ExcelのデフォルトはShift-JISであったりするらしい。

 

符号単位列からバイト列への変換

バイト列に変換

UTF-8やUTF-16によって変換されたものを「符号単位列」と呼ぶ。しかし、ファイルの読み書きや通信を行う場合、符号単位列をさらに変換し、バイト列にする必要がある。要は「0101010101…」のような01の羅列された形にしないと通信で使えないということ。

 

BOM付きとか呼ばれるやつ

符号単位列をバイト列にするときは、バイト順序(エンディアン)を気にしなければならない。エンディアンにはビックやリトルなど、複数種類があり、指定しないとコンピュータはどの順序でバイトが並べられているかわからない(エンディアンの説明はここで拙く書くよりググってもらった方が早いと思ったので省略)。そこで使用されるのがBOM(バイトオーダーマーク)と呼ばれるもので、どのエンディアンかを指定するために、符号化したテキストの先頭に数バイトのデータをつける。基本的に8ビット以外の符号単位列をバイト列に変換する際にBOMをつける必要がある。つまり、UTF-8の場合はこのBOMが本来必要ない。しかし、「このデータはUTF-8で符号化されているよ」とわかりやすくするためにあえてBOMをUTF-8に付与することもある。

 

UTF-8で符号されたテキストデータはエンディアンに関わらず同じ内容になるので、バイト順マーク (BOM) は必要ない。しかし、テキストデータがUTF-8で符号化されていることの標識として、データの先頭にEF BB BF(16進。UCSでのバイト順マークU+FEFFのUTF-8での表現)を付加することが許される。一部のテキスト処理アプリケーション(テキストエディタなど)がBOMを前提とした動作をすることがある。TeraPad、EmEditor、MIFESのようにBOMを付加するかどうかを選択できるものもある。

中略

逆にこのシーケンスがない場合、UTF-8と認識できないプログラムも存在する。たとえば、Microsoft Excelでは、CSVファイルを開くとき、このシーケンスが付加されていないUTF-8の場合は正常に読み込むことができない。Microsoft Windowsに付属するメモ帳、ワードパッドも同様である。Microsoft Visual C++は既定でBOMなしUTF-8を認識せず、システムロケール設定に応じたマルチバイトエンコーディングとみなすが、Visual C++ 2015以降ではコンパイルオプションを指定することでBOMなしUTF-8を認識することができるようになっている。
UTF-8 – Wikipedia

 

また、Microsoft Excelはデフォルトが「Shift-JIS」だが「UTF-8」も認識でき、ExcelでUTF-8のCSVファイルを読み込ませる場合、頭にBOMがついてないと出力した際に文字化けが発生するとのこと。

UTF-8の場合BOMは本来必要ないはずであるが、Shift-JISとUTF-8を区別するためにMicrosoft ExcelではUTF-8にBOMが必要になるというパラドックス的状況になっているからすげー調べてて頭を捻らされた。

 

アスキーコードとは

ASCIIは「文字符号化方式」を必要としない符号化文字集合と認識するとわかりやすい。そもそもは7ビットの符号構造(US-ASCII)であり、0から127の128通りの符号しかない単純なものだった。英語圏ではそれで十分通用したらしい。しかし、多言語化するためには全然足らず、ネットで探すと日本用とか色々な種類の符号化一覧があった。

Unicodeの最初である「U+0000 – U+007F」の頭128個目まではASCIIコードに準拠しているらしく、文字コードも色々歴史があるんだなと思った。

 

まとめ

文字コード作った人はすごいと思います。相当地道な作業だったんだと思います。これからは文字化けに寛容な心を持てそうです。以上ありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA