社内SEになりました

社内SEは本当に楽なのか?ユーザー系IT企業とSierとの違いは?これからIT企業への就職や転職を考えている人むけに、ユーザー系IT企業から社内SEに40代で転職した筆者がITエンジニアの仕事内容やプロジェクト管理のノウハウ等をご紹介。

文字コード第四回:文字符号化方式(後編)

文字コードって、とっても難しいです。

そんな文字コードの中で、文字符号化方式について、可能な限りわかりやすく解説します。

1.UTF-16UTF-32

ISO-2022-JPEUC-JP 、Shift-JIS は、複数の文字集合を利用するための文字符号化方式です。

それに対して、UTF-16UTF-32UTF-8 といった文字符号化方式は、使用している文字集合Unicode のみです。

それなら Unicode を直接利用すれば良いのでは?と普通の人は思います。

そして実際に最初は Unicode を直接利用していました。JavaC# などは今は UTF-16 を利用していると言われていますが、当初は UTF-16 というより Unicode を利用していました。

当時の Unicode は、2 バイトの固定長でした。

2 バイトの固定長だと収録できる文字数は、256 × 256 = 65,536 で、世界中の文字を収録するには全然足りませんでした。

そこで 4 バイトに拡張した UTF-32 が登場し、それまでの UnicodeUTF-16 と呼ばれるようになりました。そして新しい Unicode は 8 〜 21 ビットの可変長となり、直接利用されることがなくなりました。

そのため UTF-16 を利用している大部分のソフトウェアは、当初は Unicode を利用していたのです。

このように Unicode、UTF16、UTF-32 は固定長か可変長の違いはありますが、基本的には同じコードになります。ただし UTF-16 は 65,536 を超える文字を表現するために、サロゲートペアと呼ばれる 2 文字分のコードで 1 文字を表す手法を使っていますので、UTF-16サロゲートペアは、文字コードが異なります。

f:id:SystemEngineers:20210626075857p:plain

 2.リトルエンディアンとビッグエンディアン

UTF-16UTF-32 で少し厄介なのが、リトルエンディアン( LE )とビッグエンディアン( BE )です。

2 バイト文字の 1 桁目から格納する方式をビッグエンディアン、2 桁目から格納する方式をリトルエンディアンと呼びます。

f:id:SystemEngineers:20210626081335p:plain

これはデータをアドレス空間に格納する際、CPU によってデータの先頭から格納していく方式( BE )とデータの最後尾から格納していく方式( LE )が存在することに影響を受けています。

インテル系の CPU は LE を採用しています。プロトコルだと TCP/IP は BE 、USB は LE を採用していたり、JVMはBEを採用していたり、バラバラです。

このエンディアンが一致していると処理効率が良いのですが、逆になると少し処理効率が落ちます。

f:id:SystemEngineers:20210627115200p:plain

このエンディアンの考え方は、EUC-JP や ISO-2022-JP、Shift-JIS にはありません。

これらは「半角」文字は 1 バイトで、「全角」文字は 2 バイトですが、UTF-16(当時のUnicode)は全て 2 バイトです。

当時はコンピューターの処理能力が今ほど大きくなく、この文字のデータサイズの差を少しでも埋めるために、CPU やソフトウェアの処理効率が少しでも上がるようにエディアンの考え方を取り入れました。

さらにこのエンディアンには、BOM(Byte Order Mark)と呼ばれるコードがあります。

BOM を文字列の先頭につけることで、その文字列が BE なのか LE なのかを区別することができるようになります。

BE の BOM は FE FF で、LE の BOM は FF FE となります。

BOMをつけない場合には、文字符号化方式自体でBEかLEを宣言することになります。

つまり同じ UTF-16 でも、UTF-16 BE、UTF-16 LE、UTF-16 の3種類があり、さらにデータの並び順の違いも入れると、UTF-16 BE、UTF-16 LE、UTF-16( BE の BOM 付)、UTF-16( LE の BOM 付)、UTF-16( BOM なし)の5種類になります。

f:id:SystemEngineers:20210626185253p:plain

UTF-16( BOM なし)は、BE として扱われることが多いようです。

3.UTF-8

UTF-16 にはサロゲートペアの問題があり、UTF-32 は先頭 2 バイトの大部分が 0000 でメモリー利用効率が悪く、どっちもいまいちです。

そこで登場したのが UTF-8 です。

UTF-8 は可変長のため、固定長の文字コードよりも扱いにくいですが、コンピューターの処理性能が上がったことと、ASCⅡ と互換があることから、今や大部分のソフトウェアでは UTF-8 が使われるようになってきました。

UTF-8 は、UTF-16UTF-32 と違い、Unicode とは似ても似つかないコードになります。

f:id:SystemEngineers:20210626204140p:plain

UTF-8 の符号化方式は、以下のルールに従います。

f:id:SystemEngineers:20210626213006p:plain

このルールに従って UnicodeUTF-8 に変換すると以下のようになります。

f:id:SystemEngineers:20210626213124p:plain

U+0031 は、UTF-16 は「00 31」、UTF-32 は「00 00 00 31」です。それに対してUTF-8 は「31」で、ASCⅡ と全く同じなので重宝されているようです。

ただ漢字は 3 バイトや 4 バイトとなり、EUC-JP や ISO-2022-JP、Shift-JIS といった符号化方式よりもサイズが増えるため、一長一短なところはあります。

f:id:SystemEngineers:20210627102850p:plain

この UTF-8 にも BOM があります。

UTF-8 の BOM は「EF BB BF」です。本当は 2 バイトコードではない UTF-8 には BOM は必要ないのですが、UTF-8 であることを示すために付加されることがあります。

例えば WindowsPC で CSV ファイルをダブルクリックすると、Excel でファイルが開かれますが、このとき ExcelCSV文字コードを CP932 として扱います。もし CSV文字コードUTF-8 で作成していると、CP932 として扱われるので文字化けします。

このとき、CSV を BOM 付きの UTF-8 で作成すると、Excel は正しく UTF-8 として扱ってくれるので文字化けしません。

ただし UTF-8 の BOM に対応していないソフトウェアもあるので、その場合には「EF BB BF」も文字として扱ってしまい、文字化けの原因となるので注意が必要です。

4.まとめ

符号化文字集合文字符号化方式の説明は以上となります。

これらを図にすると以下のようになります。ちょっとごちゃごちゃして見にくいですが・・・。

f:id:SystemEngineers:20210626214735p:plain

以下は、文字コードのサンプルです。

f:id:SystemEngineers:20210705213210p:plain

どの文字コードも ASCⅡ との互換を大切にしていることがわかります。

 【振り返り】

第四回は、文字符号化方式(後編)でした。第五回は、サロゲートペアです。

第一回:概要
第二回:符号化文字集合
第三回:文字符号化方式(前編)
第四回:文字符号化方式(後編)
第五回:サロゲートペア
第六回:IVS
第七回:文字コードの歴史
第八回:文字化け