コラム

2015年6月26日 / 技術

勉強会レポ VOL.1
エンジニアなら知っておきたい文字コード


文字コードimage

こんにちは。開発第二ユニットの青木です。
社内で定期的に開催している勉強会の内容をお伝えしたいと思います。
今回は「文字コードについて」です。
以前、文字コードを扱う部署にいたこともあり、文字コードの全般的な概念と開発における注意点を簡単に説明したいと思います。

1.文字コードとは

文字コードといっても大きく分けて二つの概念があります。

  • (符号化)文字集合(CCS/coded character set)
    • どんな文字を使うのか?
  • (文字)符号化方式(CES/character encoding scheme)
    • どのように符号化するのか?

日本語であれば漢字を利用します。常用漢字だけでも数千単位で存在します。もちろんすべて扱えれば理想ですが、資源には限りがあるので、扱う文字を決める必要があります。この集まりを文字集合と呼びます。
次に各文字をデータとして扱うために数値と対応付けします。この方式を符号化方式と呼びます。
例えば、シフトJISの場合は、以下のようになります。(0xは16進数を表します)

  • 唖→0x88,0xA0
  • 娃→0x88,0xA1
  • 阿→0x88,0xA2
  • 哀→0x88,0xA3
  • 愛→0x88,0xA4

2.日本で扱う主な文字コード

2.1 ASCII/ANK(JIS X 0201)

いわゆる半角文字、1バイト文字と言われているものです。0x20~0x7E以外は制御コードと呼ばれ、一部はバックスペースやデリートキーに割り当てられています。

ANKはAlphabet Numerals and Katakanaの略です。ASCII+半角カナとほぼ同等です。

http://www.asahi-net.or.jp/~ax2s-kmtn/ref/codes.html

2.2 JIS(ISO-2022-JP)

0x2121~0x7E7Eに定義された文字コード。ASCII(0x20~0x7E)とバッティングするので、漢字INと漢字OUTという制御コードが必要になります。このため現状では電子メールくらいでしか利用されません。

http://www.asahi-net.or.jp/~ax2s-kmtn/character/japan.html

http://www.unixuser.org/~euske/doc/kanjicode/

2.3 シフトJIS

JISコードの問題点(ASCIIとの区別に制御コードが必要)を改善するためwindows系で考えられた文字コードです。WindowsではCP932という名前で呼ばれています。ANKの未使用領域(0x80~0x9F,0xE0~0xFF)を1バイト目に利用することで制御コードを利用することなくANKと区別できるようにしています。このためJISコードの領域を分割して再配置しているので少し複雑です。

2.4 EUC(EUC-JP)

シフトJISと同様にJISコードの問題点を改善するためにUNIX系で考えられた文字コードです。EUCの半角文字はANKとは別なので0xA1A1~0xFEFEにそのまま移動しています。

3.日本語を扱う文字セット

JISという日本の規格で定義されています。Unicode以前のものはJIS X 0208でUnicodeはJIS X 0213です。
規格の後ろには制定された年と入り、規格の略称としてJIS83/90とかJIS2004というキーワードはよく出てきます。

  • JIS X 0208(Unicode以前)
    • JIS X 0208-1990(JIS83)
    • JIS X 0208-1990(JIS90)
  • JIS X 0213(Unicode)
    • JIS X 0213:2004(=JIS2004)

4.日本文字コードその他

4.1 外字

文字セットで扱っていない文字を表示するには、「外字」と呼ばれるマシンごとに独自に定義する文字を利用するしかありません。ただし外字を含むデータを複数のマシン間で扱う場合には、外字の定義を共有する必要があります。人名を扱う自治体のシステムでは外字の問題を避けて通れません。

4.2 機種依存文字

昔のパソコンでは扱える文字が少なかったため空き領域に各種ベンダが文字を割り当てていました。いわゆる丸囲み文字などです。同じベンダのマシンであれば問題ありませんが、インターネット(電子メール)の普及とともに文字化けの問題が出てきました。ガラケーの絵文字が化ける問題も同じ理由です。

http://www.asahi-net.or.jp/~ax2s-kmtn/character/japan.html#machine_depend

4.3 JIS2004問題

Windows VistaからUnicode対応のため、文字セットがJIS2004に変更されることになりました。しかし以下の問題のためコンピュータ業界ではちょっとした騒ぎになりました。

  • 字体変更
    • 同じデータでもVistaでは表示する字形が変更されてしまいます。多くは一点しんにょうが二点しんにょうになるなどの軽微なものですが、それでも困る場合はあると思います。たとえば人名や会社名、商品名の表記が変わったら困りますよね?
    • http://www.asahi-net.or.jp/~ax2s-kmtn/ref/jis2000-2004.html
  • サロゲートペア
    • Unicodeを策定していく過程でイレギュラー的に発生した拡張方式です。詳細は以下で説明しますが、アプリケーション側での対応を余儀なくされました。

5.Unicode

インターネットの普及により、それまでばらばらだった文字コードの統一化の必要性が高まり、大手ベンダが集まったユニコードコンソーシアムによって策定されました。

日本では、JIS規格として以下のように規定さてています。

  • 文字集合:JIS X 0213
  • 符号化方式:JIS X 0221(ISO/IEC 10646)

以下ではUnicodeで扱う概念を説明します。

5.1 コードポイント

U+xxxxで表されるUnicodeの論理的な場所を表す値です。0x0000~0xFFFFを一つの面として複数の面が存在するイメージです。

5.2 BMP

Unicodeの概念を考える場合、0x0000~0xFFFFからなる一番初めの面をBMP(基本多言語面:Basic Multilingual Plane)といいます。当初は一つの面だけでしたが、定義する領域が足りないことが分かり、複数の面を扱えるように拡張されました。

https://ja.wikipedia.org/wiki/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2

5.3 UTF-8/UTF-16/UTF-32

Unicodeのエンコーディング方式です。現状UTF-8以外はほぼ使われないでしょう。

UTF-8は1文字を1バイトから6バイトまでの可変長になります。1バイト目の値で一文字が何バイトになるか分かれています。またASCII文字と互換が取れるようになっています。

UTF-16は1文字を2バイト固定長で表しますが、サロゲートペアという拡張方式により拡張が可能です。

UTF-32は1文字を4バイト固定長で表します。

https://ja.wikipedia.org/wiki/Unicode#.E6.96.87.E5.AD.97.E7.AC.A6.E5.8F.B7.E5.8C.96.E3.82.B9.E3.82.AD.E3.83.BC.E3.83.A0

5.4 BOM

バイトオーダーマーク。バイトの並び順の事です。CPUの種類によって複数バイトからなるデータを扱う場合、そのままの並び順をビッグエンディアン(BE)、ひっくり返した並び順をリトルエンディアン(LE)と呼びます。例えば、0x1234の場合、ビッグエンディアンは0x12,0x34という並び順になります。リトルエンディアンの場合は0x34,0x12という並び順になります。Windowsマシンはリトルエンディアンになります

https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3

UTF-16とUTF-32はエンディアン識別のため、以下のデータがファイルの先頭に追加されます。

  • UTF-16 BE→0xFE,0xFF
  • UTF-16 LE→0xFF,0xFE
  • UTF-32 BE→0x00,0x00,0xFE,0xFF
  • UTF-32 LE→0xFF,0xFE,0x00,0x00

5.5 サロゲートペア

Unicodeを策定していく過程でイレギュラー的に発生した拡張方式です。当初はBMP一面だけでカバーできる予定でしたが、蓋を開けてみれば全然足りなかったのです。特定のコード領域(前半 U+D800~U+DBFF、後半 U+DC00~U+DFFF)を使った4バイトで1文字を合わらすことによって、扱える文字数を拡張しています。

これはUTF-16というエンコーディングで発生する問題なのですが、Windowsの内部コードがUTF-16だったため前述したJIS2004問題ではサロゲートペアを考慮せざるを得なかったのです。

https://ja.wikipedia.org/wiki/Unicode#.E3.82.B5.E3.83.AD.E3.82.B2.E3.83.BC.E3.83.88.E3.83.9A.E3.82.A2

5.6 UCS-2/UCS-4

1文字を2バイトで表す方式をUCS-2、1文字を4バイトで表す方式をUCS-4と呼びます。厳密にはUnicodeとは別の規格になりますが、概念としてはUCS-2=UTF-16、UCS-4=UTF-32となります。 あまり使われませんが、たまに出てくるキーワードなので一応覚えておきましょう。

http://www.d2.dion.ne.jp/~imady/charset/ucs.html

6.プログラミング言語で扱う文字コード

6.1 PHPのマルチバイト対応関数

ASCII以外の文字列を扱う場合、’mb_’から始まる関数を利用する必要があります。指定したエンコーディングの方式によって1文字が複数バイトであること考慮してくれます。逆にこれらの関数を利用しない場合は、誤認識を起こす可能性があります。

http://php.net/manual/ja/ref.mbstring.php

6.2 PHPで扱うエンコーディング

例えば、EUC-JPとeucJP-win、SJISとSJIS-winがありますが、後者(winが付いたもの)は、機種依存文字を考慮した変換が可能になります。

http://php.net/manual/ja/mbstring.supported-encodings.php

7.補足

以下も読んでおくとよいと思います。

http://gihyo.jp/admin/serial/01/charcode

この記事を書いた人

青木 康展
システム開発者。歴はそこそこ長い。最近はcakePHPを利用したWebシステムの開発がメイン。技術者として生涯現役を目指す。たぶん。趣味はビリヤードと料理、そして犬と戯れること。

この人が書いた記事

  • 遊びイベレポ vol.6<br />『お台場「大江戸温泉物語」で休日の午後をまったり過ごそう♪』

    遊びイベレポ vol.6
    『お台場「大江戸温泉物語」で休日の午後をまったり過ごそう♪』

    イベント

    2015.10.29

  • コミュニケーション予算レポ<br />『オトナ男子の“大人飲み”』

    コミュニケーション予算レポ
    『オトナ男子の“大人飲み”』

    イベント

    2015.10.20

  • 勉強会レポ VOL.2<br />『最近のセキュリティ事情について』

    勉強会レポ VOL.2
    『最近のセキュリティ事情について』

    技術

    2015.8.7

  • 勉強会レポ VOL.1<br />エンジニアなら知っておきたい文字コード

    勉強会レポ VOL.1
    エンジニアなら知っておきたい文字コード

    技術

    2015.6.26

その他の最新記事

Read More >>