やぼったい開発 > 早わかり 文字コード 15分講座 > 日本語の代表的なエンコード

日本語の代表的なエンコード

--

エンコードの概要

エンコード種類

おおざっぱに言うと、文字集合をコンピュータ上で表したときの番号体系です。 文字セットのIDと表示コードがイコールの時もあれば IDを計算し変換したりもします。 符号化とも言います。 主なエンコード方式は JIS,シフトJIS,EUCがあります。

細かいコードや区点の話は、はしょる予定です。
コード体系ベース類似コード
JISJIS X 0208
Shift-JISJIS X 208CP932,Shift_JIS,Windows-31J,MS932
EUCJIS X 0208
UNICODEJIS X 0213
※類似コードはざっくりいうと確かに違いますが、大きな違いはありません (怪しい文字や機種依存文字は使わないようにしておけば大丈夫です)。

エンコード方式の特徴

固定長

固定長であれば計算や処理が単純になりますが、実行時にならなければ文字長がわからない場合、処理が複雑になります。

バイトコードを解釈するコスト

ASCIIの頃はたった1バイトでしたが 2byte,3byteと殖えてしまうと、それだけで解釈や対応コストがかかります。例えば英語圏なども影響を受け、使いもしない2byteコードのソフトを作らなければなりません。また、エンコード方式が複雑であるほど、変換や解釈にコストがかかることになります。

同時表現可能性

日本語だけ表示するのであれば問題ありませんが、中国語などと多国語を同時に表現する場合、Shift-JISだけでは表示しきれません。そこで多言語対応を目的として Unicodeが発案されましたが、切り替え方式ではないため、全ての文字を1元管理するという方向になっています(おそらく柔軟性がないため、拡張するたびに大きなコード体系の変更があったり、領域が不足したときに、文字を合わせたりと無理がある気がします(実際ハングル文字の大移動がありました))。

JIS

JIS符号化はJISコードそのままのコード体系を使う。区点コード参照。
そのままでは、ASCIIと漢字との切り替えができないので、2byte文字を使う時の切り目としてエスケープシーケンスという目印を書きます。
その「エスケープシーケンス」と呼ばれる特殊な文字列を目印にして切り替えます。

エスケープシーケンスによる切り替え
エスケープシーケンス切り替え内容
ESC $ @漢字の開始(旧JIS漢字 JIS C 6226-1978)
ESC $ B漢字の開始 (新JIS漢字 JIS X 0208-1983)
ESC & @ ESC $ B漢字の開始 (JIS X 0208-1990)
ESC ( BASCIIの開始
ESC ( JJISローマ字の開始
ESC ( I半角カタカナの開始
〔補足〕JIS X 0213附属書2のIS0-2022-JP-3符号化表現では、[ESC] $ ( Oというエスケープシーケンスで1面の漢字集合に、[ESC] $ ( Pで2面に切り替えることになっています。

句点による文字種の区分
文字数文字種
1-2147各種記号
362数字、ローマ字
483ひらがな
586カタカナ
648ギリシャ文字
766キリル文字
832罫線素片
9-150未定義
16-472965第一水準
48-843390第二水準
85-940未定義
ISO-2022 はエスケープシーケンスで切り替えるため、一時的な仮想テーブル(GL バッファ)をその同じタイミングで切り替えてそこを呼び出すように使うらしい。おそらくこれがISO 2022で定義されている符号拡張方式。インターネットの電子メールで用いられるJISコード(ISO-2022-JPもしくはJUNETコード)は、このサブセットを使って簡略化した形で符号化を行なっています(RFC1468)

またマルチコードの 2byteであるため 区点コード区分の 94区分 x 94 文字がJISコードに対応します。 0-127(7bitなので)のうち 94文字を利用します(8bitもあるそうです)。

今 JIS規格で「JIS」という単語を使うことはあるが、このようなエンコードを意味してJISと言う機会は減少していると思われる。この場合 ISO-2022-jpという言い方をする(メールの場合良く使う)。

シフトJISコード

SJIS、MS漢字とも呼ばれ現在パソコンの多くで使われている文字コードです。 CP932,Shift_JIS,Windows-31Jなどがあります。

1バイト仮名(X 0201)で未定義領域になっている部分を使って漢字(X 0208)を表現することで、エスケープシーケンスなしで1バイト文字と2バイト文字を共存できるようにしたものです。そのためにJISコードを移動(シフト)させたことからこう呼ばれます。

JISコードのような専用の切り替えコードがあるわけではなく、 1byte目が129〜159、224〜239(0x81〜0x9F、0xE0〜0xEF)の範囲の時、2byte文字として認識します。 次の文字の第2バイト目は64〜126、128〜252(0x40〜0x7E、0x80〜0xFC)の範囲です。 第1バイトの範囲は、英数字(ASCII、0x21〜0x7E)や1バイト仮名(半角カナ、0xA1〜0xDF)と重複しないように配置されています

1byte コードは 209文字分
2byte コードは 8836文字表現可能です
 (1byte目 (31+16)* 2byte目(63+125))
    == 94 * 94(JIS コードポイント))


特徴

・8ビット目を使用しているため、電子メールでは送れません(8bit目がロストする可能性があるので)。
(・コードが分断されており体系として不自然なためソートに向きません。)
・ASCIIや半角仮名コードが1byteと明確で、共存できます。
・半角コードを分けているため、 スペース的に0208までしか用意できません。
・バイト数から文字数が判断付きません(Shift-JISの規格上ある程度判断できるし、制御コードは元々判断できませんが)。

CP932兄弟の話

Shift-JIS の良さに目を付けたマイクロソフトは CP932として採用しました。 (ちなみに同じコードで地域や言語の違いを表すためにページを切り替えて使っていました。 そのページを CP 「コードページ」といいます)

IBMはCP932を拡張しIBM CP932を、 NECはPC-9800仕様OEMコードページ932 を作りました。 のちのち マイクロソフトはIBMとNECのコードページを統合し Windows 3.1にのせ コードぺージ932と再命名しました。 しかし、IANAから違う物なら別名を付けるべきと物言いが入り、Windows-31Jと名称を決めました。

実際はその名称は広がらず、相変わらずCP932と呼ばれ続けているうちにWindowsが普及し始めた。 そののち、Javaが出てきた頃にIBMのコードページと対比するように このWindows-31JのことをMS932というように言われ始めたのが現在です。


ちなみに 「NEC選定 IBM拡張文字」もあるからややこしいです。

MS932 = Windows-31Jですが、 CP932はどれを正確に指すかわかりません。 Shift-JISの拡張文字部分がMS932は 定義されています。 windows,mac(09〜15区)の機種依存文字はこの兄弟の差分です。 特に Windowsの機種依存文字は根が深いです。 windowsは09区〜15区および85区〜94区の一部、ならびに、 JIS漢字の範囲外である95区〜114区の一部が機種依存領域です。 iモードの絵文字は 112〜114区を使用しています。

http://www2d.biglobe.ne.jp/~msyk/charcode/cp932/index.html
Windows-31J 情報

http://d.hatena.ne.jp/akumakario/20080522/1211452983
Shitf_JISとCP932とMS932とWindows-31Jを昔話風に語ってみた

符号化

4つに分かれた箇所を、どのように連続的なJISコードと対比させるかが重要です。

JIS, EUC, SJIS の漢字コードについて[外]

Shift-JIS のコーディング[外]

EUC

EUCには可変長コードと固定長コードの2とおりありますが、一般的なのは可変長(圧縮フォーマット)の方です。 G0〜G3に割り当てます。
EUCで扱う文字コード
セット 第1バイト 第2バイト 第3バイト 日本語EUCの場合
G0 0x21〜0x7E - - ASCII
G1 0xA0〜0xFF 0xA0〜0xFF - JIS X 0208-1990(新JIS)
G2 0x8E 0xA0〜0xFF - JIS X 0201カナ(1バイト仮名)
G3 0x8F 0xA0〜0xFF 0xA0〜0xFF JIS X 0212-1990(補助漢字)
JIS X 0213では、SS3によって呼び出すG3には、補助漢字ではなくX0213の第2面の漢字が割り当てられます。

現在一般的に EUCを言うときは JIS X 208ベースのことを言う。 212、213ベースもあるが、おそらくユニコードが広まってきている現在あまり普及はしないと思う(EUCをカバーするのであれば、UTFをカバーするはずなので)。

符号化

一般的なEUCはJIS X 0208ベースなので、半角カナ文字はJIS漢字にないがそれ以外についてのコード変換は単純です(Shift-JISがややこしすぎるだけ)。上の表のようにG1部分のEUC 漢字コードは JIS 漢字コードの 2バイトのそれぞれの 第7ビット目を1にしてあるだけなので (0x21 → 0xA1, 0x7E → 0xFE となる)、第7ビット目を 立てれば EUC になるし、おろせば JIS になるのである。

そのため EUC Shift-JIS間の変換が JISにいったん変換させずともそれほど難なくできるようになる。

G3の補助漢字や JIS X 213については、基本同じだが対象が少し違うため、少し変換ロジックが追加で必要になる。

ユニコード

符号化方式

Unicodeの符号化方式に UTF-8,16,32があります。

UTF-1,7はあまり使われていません。 UTF-32はこれからなので普及するかどうか不明です。
UTF符号化方式 bit OS
UTF-7 7bit
UTF-8 8ビット単位の可変長コード(1〜4バイト)
UTF-16 BMP (基本多言語面)を16ビット、その他を#サロゲートペアという仕組みを使い32ビットで指定する方式。 Windows XP
※マイクロソフトがUnicodeに対応したのは,「Windows 98」と「Windows NT 4.0」からです。 だ。このとき,「JIS X 0212」の「補助漢字」も「Microsoft IME」の辞書に登録され, エンコーディングにUnicodeを使えばWindowsで利用できるようになりました。

UTF-7

UTF-16 (後述)で表したUnicodeをBase64で変換して表す方式。 ただし、ASCIIのアルファベット範囲等についてはBase64に変換しない等、 特殊なエンコーディングを行います。 ステートフル通信など運用上問題が多いため、 現在ではこの方式は推奨されずUTF-8を使います。

UTF-8(UTF-2、UTF-FSS)

8ビット単位の可変長コード(1?4バイト)にエンコードする方式。 ASCIIに対して上位互換となっており、文字の境界が明確です。 エンコード・デコードに際して乗除算などの負荷の高い処理が必要ないなどの特長を持ち、 インターネットではもっとも一般的に利用されています。

UTF-16

BMP (基本多言語面)を16ビット、その他を サロゲートペアという仕組みを使い32ビットで指定する方式。 Windows XPなどの近年のOSの内部コードには、 この形式が使われている。UCS-2ともBMPの範囲で互換性がある。

UTF-32 (Unicode 3.1より)

Unicodeの全コードを単一長のコードとして32ビットで指定する方式。実際に使われるのは21ビット(Unicodeの空間がU+10FFFFまでであるため)。この21ビットの範囲内ではUCS-4と互換性がある。

単純な符号化方式であるが、テキストファイルなどでは文章のサイズが大きくなるため (全てBMPの文字からなる文章の場合はUTF-16符号化の2倍のサイズとなる) 使用されることは稀です。 ちなみにMicrosoft Officeでのエンコードされたテキストファイルの読み書きは この符号化方式には未だ対応していません。

その他

UTF-5,9は確定せず、破棄された。UTF-9,18はジョークです。

BOMとビックエンディアン

BOM (Byte Order Mark) とは、8ビットを基本とするシステムで バイトオーダーを識別するための印であり、データストリームの先頭に付与されます。

MIMEなどの手段で文字符号化方式にUTF-16BEやUTF-16LE(UTF-32BE,UTF-32LE)を 指定している場合にはBOMを付与することは許容されません。
UTF符号方式 BOM(値はU+FEFF) 備考
BOM(UTF-8のみ) エンディアン付き
ありなし(N) ビックエンディアンリトルエンディアン
UTF-8 データストリームの先頭に EF BB BF の3バイトが付与される
UTF-16 エンディアンの項参照 UTF-16BE:0xFE,0xFFUTF-16LE:0xFF,0xFE
UTF-32 UTF-32BE:0x00,0x00,0xFE,0xFFUTF-32LE:0xFF,0xFE,0x00,0x00

UTF-8

日本国内でのみ、BOMがついているものをUTF-8、ついていないものをUTF-8Nとして区別することがあるが、国際的には認知されていません。もともと8ビットを基本とするUTF-8ではBOMを付与する必要はありませんが、UTF-8であることが識別できるようにしています。

Windowsのメモ帳で作成した「Unicodeテキスト」には標準でBOMが付与される。 Internet Explorerでは、BOMのついていないUTF-8の文書を読み込むと (日本語版の場合)Shift_JISだと誤認するようです。

UTF-16

RFC 2781 ではBOMが付いていないUTF-16文書はビッグエンディアンとして解釈することになっています。

Windowsのメモ帳で作成した「Unicodeテキスト」は標準でBOMが付与されるようになっています。

・Windows上の文書における「Unicodeテキスト」は特に明記のない場合につき、リトルエンディアンのUTF-16のことを指します。
・TCP/IPネットワークではプロトコルヘッダやMIME等の手段で文字符号化方式が指定されずBOMも付与されない場合、ビッグエンディアンに決められています。

UTF-32

UTF-16のリトルエンディアンとUTF-32のリトルエンディアンは 最初の2バイトが等しいため、4バイトまで読んで判断する必要があります。

サロゲートペア(UTF-16)

Unicodeでは代用対をサロゲートペア(英: Surrogate Pair)の日本語表記としている。

サロゲートペア(代用対)は16ビットUnicodeの未定義領域1024文字分を2つ使い(前半0xD800?0xDBFF, 後半0xDC00?0xDFFF)、それをペアにすることで1文字を表し (1024 × 1024 = 1,048,576文字)、その1,048,576文字を256 × 256の区点 (row, cell) からなる「面」 (plane) に順番に割り振っていく。これにより 1,048,576 / (256 × 256 = 65,536) = 16 で、全部で第16面までの文字を収録することができる。つまり第01面から第16面までであり、これに加えて第00面 (BMP) も使用可能なので、合計で 1,048,576 + 65,536 - 2,048 = 111万2,064文字が使用可能になる。

エスケープシーケンスこそ使用しないものの、16ビット文字コード体系との互換性を維持するために、UTF-16(16ビットを符号単位とする文字符号化形式)を採用した結果、 Unicodeは16ビット符号単位一つと16ビット符号単位二つ(合計32ビット)が混在する複雑な可変長文字コードとなってしまった。

サロゲートペア(代用対)の方式は16ビット固定長を志向したUTF-16との互換性維持のために設けられた拡張であり、UTF-8やUTF-32では利用できない。

(wikipedia より)

Unicodeは 2^16 = 65,536 種類の文字を収録でき、当初の構想では世界中のすべての文字をこの16ビット固定長のコード体系に登録可能と思われていた。、Unicodeの16ビット枠内に全世界の文字を収録するという計画は早々に破綻し、1996年、Unicode 2.0ではサロゲートペア(代用対)の拡張が盛り込まれた。


Unicode 1.0公表後、拡張可能な空き領域2万字分を巡り、各国から文字追加要求が起こった。その内容は中国、日本、台湾、ベトナム、シンガポールの追加漢字約1 万5千字、古ハングル約5千字、未登録言語の文字等々である。このため計画は早々に破綻しています。


(wikipedia より)

符号化の実装

libiconv(GNU)

Yu TANAKA's Works:S-JISからUTF-8への変換(Borland C++6)

まとめ

JISコードはエスケープシーケンスがあるため、切り替えられますが 解析しなければ、文字数を求めることができません。 また、検索も同様です。


早わかり 文字コード 15分講座 に戻る。







やぼったい開発 > 早わかり 文字コード 15分講座 > 日本語の代表的なエンコード(早わかり 文字コード 15分講座)