情報のデジタル表現



1 音声のデジタル表現:標準方式=PCM

 コンピュータは情報を「0」と「1」で表現しますので、デジタルでの表現が得意です。デジタル量をデジタルで表現することはもちろん、アナログ量もデジタルに変換して表現します。アナログ量をデジタル表現に直す方法をアナログ/デジタル変換(A/D変換)といいます。コンピュータは内部での処理を全てデジタルで行います。デジタルで処理したデータをアナログ量に直す必要がある場合もあります。アナログ量しか表現できないような表示器具もあるからです。デジタルをアナログに変換する方法をデジタル/アナログ変換(D/A変換)といいます。

 人間の声などはアナログ量のいい例です。次に、音声の波形を示します。


 このアナログデータをどのようにデジタル化するかですが、まず等間隔に縦に千切りにします。これをサンプリング(標本化)といいます。1秒間に切った回数をサンプリング周波数といいます。


 縦に千切りにしたものを今度は横に切っていきます。これを量子化といいます。回数は2のべき乗回数が好都合です。


 グラフに棒グラフを対応させて目盛りを読み取ると左から、5、11、16、18、16、12、13、17、18、19、19、21、19、10、2、8、11、10、2、8、19、22となります。これを5ビットの2進数に変換すると(32段階で量子化)、00101、01011、10000、10010、10000、01100、01101、10001、10010、10011、10011、10101、10011、01010、00010、01000、01011、01010、00010、01000、10011、10110となります。これを並べると(符号化)、次のようなデジタルデータとなります。「00101010 11100001 00101000 00110001 10110001 10010100 11100111 01011001 10101000 01001000 01011010 10000100 10001001 110110...」

 アナログ信号をデジタルデータにサンプリングする場合には標本化定理というものがあります。

標本化定理
 原信号に含まれる最大の周波数成分をf[Hz]とするとき、1/2fの時間間隔で波形値のみを取り出しても、情報の損失はない

 原信号に含まれる最大の周波数成分(最高周波数)さえ定義できれば、情報の損失なくデジタル化できるというのが標本化定理の言っていることです。

※この標本化定理は米国の物理学者のナイキストによって予想され、後に情報理論の創始者であるシャノンによって証明されました。そのため、ナイキストの定理、あるいはナイキストシャノンの定理とも呼ばれます。

 量子化については明確な基準はありませんが、ビット数を多くとり量子化の間隔を小さくすればするほどデジタル化の精度は上がります。しかし、量子化の際の誤差をゼロにすることはできません。この誤差のことを量子化誤差といいます。

 これで音声をデジタル化する方法が分かっていただけたと思います。上に説明したのは音声のデジタル化で最も標準的なPCM(Pulse Code Modulation、パルス符号変調)という方法です。

 音楽CD(CD-DA)はPCM方式を採用しています。PCMでは周波数帯域を20kHzまで、周波数44.1kHzで標本化(1秒間に44100回の数値化)し、16ビットで量子化しています(0~65535の65536段階)。


2 画像のデジタル表現

 画像情報をデジタル表現する方法としてはラスタ形式とベクタ形式があります。

 ラスタ形式は画素とかピクセル(pixel)と呼ばれるものを集めて画像を構成する形式です。ピクセルは縦横を細かい碁盤の目のような小さな四角形に区切り、各四角形に色や濃度の情報を割り当てます。ペイント系のソフトで描くとラスタ形式で保存されます。ペイント系の画像の形式としては、JPEG、PNG、GIF、BMPなどがあります。

 これに対して、ベクタ形式は「アンカー」と呼ばれる座標の点を複数作り、そのアンカー同士を線でつないだり、あるいは直線や曲線の式により幾何学的な情報の集合として表現する形式です(Y = Xのグラフ、x2+y2 = 32のグラフなど)。ドロー系のソフトで描くとベクタ形式で保存されます。ドロー系ソフトとしては、AdobeのIllustratorなどが有名です。

 ラスタ形式は様々な色の点(といっても四角形)を並べるので、風景などの複雑な絵を表示するのに適しています。ただし、ピクセル単位で処理をしていますので、拡大するとピクセルの四角形が目立ってしまいます。ベクタ形式は点と点を直線で結んだり、数式で処理したりしていますので、拡大しても輪郭がとてもきれいです。

 コンピュータのディスプレイはラスタ形式ですので、ベクタ形式の画像はそのままではディスプレイに表示することができません。ベクタ形式の画像をディスプレイ上に表示するには、ベクタ形式をラスタ形式に変換して表示しています。他の形式のデータをラスタ形式にすることを「ラスタライズ」といいます。複雑なベクタ形式の画像の場合は、ラスタライズに時間がかかります。ベクタ画像は写真や細密画などの処理が特に不得意です。その代わり、直線や曲線などで構成される図形の表示に向いています。

 ベクタ画像はアンカー座標の数値や、直線、曲線の式などしか記録していませんので、ファイルサイズは非常に少なくなります。これに対して、ラスタ画像は画素データを全部保存しなくてはなりませんので、ファイルサイズが大きくなってしまいます。

 画像データの各画素は明るさや色の数値で表現されます。モノクロ画像の場合は色の明るさで、カラー画像の場合は赤、緑、青の光の3原色の明るさで表します。各色を8ビットで表現すると(0~255の256段階)、各画素は24ビット(0~16,777,215の16,777,216段階)で表現されます。赤、緑、青の各要素をビットで表現した値をRGB値といいます。

 次に各色を3バイト(24ビット)で表現した例を示します。各要素は16進表示になっています。

 最初は単色の例です。

R=FF,G=00,B=00 R=00,G=FF,B=00 R=00,G=00,B=FF
R=80,G=00,B=00 R=00,G=80,B=00 R=00,G=80,B=00
R=40,G=00,B=00 R=00,G=40,B=00 R=00,G=00,B=40

 次は2色混合の例です。
R=FF,G=FF,B=00 R=00,G=FF,B=FF R=FF,G=00,B=FF
R=80,G=80,B=00 R=00,G=80,B=80 R=80,G=00,B=80
R=FF,G=80,B=00 R=00,G=FF,B=80 R=80,G=00,B=FF
R=80,G=FF,B=00 R=00,G=80,B=FF R=FF,G=00,B=80

 次は3色混合の例です。
R=FF,G=FF,B=FF R=FF,G=80,B=40 R=FF,G=40,B=80
R=80,G=80,B=80 R=80,G=FF,B=40 R=40,G=80,B=FF
R=40,G=40,B=40 R=40,G=FF,B=80 R=80,G=40,B=FF

 画像データを拡大すると小さな四角形のピクセルによって構成されていることが分かると思います。そのピクセルの1つ1つが赤(Red)、緑(Green)、青(Blue)の情報を持っています。

 各ピクセルにRGBの情報を関連付ける方法としては、各ピクセルに直接RGBの情報を持たせるRGBカラー方式方法(true color方式、あるいはfull color方式とも呼ばれます)と、各ピクセルをカラーマップ(color map)で定義した番号を使って表現する方法(index color方式とも呼ばれます)があります。

 RGBカラー方式では1つ1つのピクセルを一般的に2バイト、3バイト、あるいは4バイト程度で表現します。これに対して、カラーマップ方式では色を4ビット(0.5バイト)あるいは1バイトの番号で表示し、その番号に対してRGBカラーを別の表の形で管理します。

 RGBカラー方式の例を次に示します。R、G、Bの各色のデータはそれぞれ1バイトずつ、1ピクセル当たり3バイトで表現しています。下の例では、左上の隅のピクセルはRedが0x35、Greenが0x91、Blueが0x40で、RGBは0x359140です。左上から順に3つのピクセルは合わせると、「0x3591402539171DFF83」という情報を持っていることになります。もちろん、実際の情報は2進数で保管されています。


 以上から分かるように画像データは明るさ、あるいは3原色の明るさで表される画素(ピクセル)が格子状に集まったものなので、画像データの大きさはピクセル数×1ピクセルのバイト数で表すことができます。1ピクセルのデータが3バイトだとすると、解像度が横1280×縦1024の場合、ディスプレイに映っている画像のデータの大きさは1画面で1280×1024×3=3,932,160バイトということになりますので、大体4MB程度ということになります。

 カラーマップ方式では次のような色のマップを予め定義し、この色に対してindex番号を割り当て、この番号を各ピクセルに割り振っていきます。次の例は、R、G、Bをそれぞれ1バイトずつで合計3バイトの色の情報に4ビットのindexを割り当てています。indexのビット数によって選択できる色の数が決まってきます。4ビットの場合は16種類の色を使うことができます。

番号 R G B
0 00 00 00
1 FF E0 FF
2 FF 60 60
3 00 E0 00
4 00 A0 00
5 00 FF FF
6 00 FF E0
7 00 FF A0
8 E0 00 FF
9 A0 00 FF
A 60 00 FF
B E0 E0 E0
C A0 A0 A0
D 60 60 A0
E 60 FF FF
F 00 60 00
 
 上のカラーマップで画像を表現すると、次のようになります。


 RGBカラー方式は画像のデータの量が多くなります。これに対してカラーマップ方式は定義する色の数次第ですが、RGBで表現できる全ての色を定義するわけではありませんので、データの量が小さくなります。ただし、カラーマップは表現できる色が少ないという欠点があります。カラーマップ方式は写真のように色を大量に使用する画像には向いていませんが、ロゴのようなあまり色数を使わない画像を表現するには向いており、現在も利用されています。indexを1バイト使えば256色を利用できます。この程度使えるとアイコンやロゴマークなどには十分ですので、Web用の画像などにはよく利用されています。カラーマップを利用するものとしてはGIF形式の画像が代表的です。

 今まで断りなく「画像」と言ってきましたが、断りなく「画像」といった場合には、一般的には「静止画」を指します。動画は「映像」、「動画」などというのが一般的です。




3 文字コード

 文字も数値で表現することができます。文字を数値で表す方法は画像データ表現のカラーマップの方法と同じです。予め「A」「B」「C」などの文字に対して数値のコードを割り当てます。これを文字コードといいます。文字コードとしては、ASCIIコード、JISコード、EUCコード、シフトJISコード、UNICODEなどがあります。このコードに対して書体のデータを割り当てていきます。この書体データは一般に「フォント」と呼ばれています。

3.1 フォント

 フォント(font)は、元々は「同じサイズで、書体デザインの同じ活字の一揃い」を指す言葉です。金属活字で印刷する時代から使用されてきた言葉ですが、現在はコンピュータの画面上に表示したり、プリンターで印刷したりする場合にも利用できる電子的な書体データを指す場合にも使われます。金属活字の時代から書体に関わってきた人は両者を区別するためにコンピュータ用の書体データはデジタルフォントと呼ぶ人もいます。

 フォントには様々なものがあります。データ形式としては画像データのラスタ形式のように格子状の升目の1つ1つに色を付けて文字を表現するビットマットフォントや、画像データのベクタ形式のように線の位置や形、長さなどで文字を表現するスケーラブルフォントや、文字の輪郭線の形状を関数曲線の情報として持つアウトラインフォントなどがあります。

 利用できるシステムとの関係では、Windows、Macintoshで共通に利用できるTrueTypeフォントがあります。2次Bスプライン曲線で字形を制御しますが、ビットマップフォントも内蔵しています。LinuxやFreeBSD、MAC OS Xでも利用可能です。

 Macintoshで普及しているフォントにはPostScriptというフォントがあります。PostScriptフォントは三次ベジェ曲線を使って字形を制御しています。

 これ以外ではWindows、Macintoshのでの互換性を実現したOpenTypeフォントがあります。OpenTypeフォントは、True TypeとPostscriptの2つの形式を持っています。

3.2 ASCIIコード

 ASCII(American Standard Code for Information Interchange、情報交換のためのアメリカ標準コード)は1963年にASA(American Standard Association)によって定められたコードです。規格化された当時は7ビットの処理が主流でしたので、7bit 128文字で構成されています。制御文字が34文字、印刷可能文字が94文字です。

00 10 20 30 40 50 60 70
00 NUL DLE SP 0 @ P ` p
01 SOH DC1 ! 1 A Q a q
02 STX DC2 " 2 B R b r
03 ETX DC3 # 3 C S c s
04 EOT DC4 $ 4 D T d t
05 ENQ NAK % 5 E U e u
06 ACK SYN & 6 F V f v
07 BEL ETB ' 7 G W g w
08 BS CAN ( 8 H X h x
09 HT EM ) 9 I Y i y
0A LF SUB * : J Z j z
0B VT ESC + ; K [ k {
0C FF FS , < L \ l |
0D CR GS - = M ] m }
0E SO RS . > N ^ n ~
0F SI US / ? O _ o DEL

 上の表は一番上の行が上位ビットを、一番左の列が下位ビットを表していますので、例えば、「J」を指定したい場合は、上位ビット「0x40」、下位ビット「0x0A」を指定します。つまり、「J」は「0x4A」ということになります。

00 10 20 30 40 50 60 70
00 NUL DLE SP 0 @ P ` p
01 SOH DC1 ! 1 A Q a q
02 STX DC2 " 2 B R b r
03 ETX DC3 # 3 C S c s
04 EOT DC4 $ 4 D T d t
05 ENQ NAK % 5 E U e u
06 ACK SYN & 6 F V f v
07 BEL ETB ' 7 G W g w
08 BS CAN ( 8 H X h x
09 HT EM ) 9 I Y i y
0A LF SUB * : J Z j z
0B VT ESC + ; K [ k {
0C FF FS , < L \ l |
0D CR GS - = M ] m }
0E SO RS . > N ^ n ~
0F SI US / ? O _ o DEL


 制御コードの意味は次の通りです。

16進数 コード名 意味
00 NUL NULL(空白)
01 SOH ヘッディング開始
02 STX テキスト開始
03 ETX テキスト終結
04 EOT テキスト伝送終了
05 ENQ 問い合わせ
06 ACK 肯定応答
07 BEL 警告
08 BS 後退
09 HT 水平タブ
0A LF 改行
0B VT 垂直タブ
0C FF 書式送り
0D CR 復帰
0E SO シフトアウト
0F SI シフトイン
10 DLE 伝送制御拡張
11 DC1 装置制御1
12 DC2 装置制御2
13 DC3 装置制御3
14 DC4 装置制御4
15 NAK 否定応答
16 SYN 同期信号
17 ETB 伝送ブロック終結
18 CAN 取り消し
19 EM 媒体終了
1A SUB 置換キャラクタ
1B ESC 拡張
1C FS ファイル分離キャラクター(→)
1D GS グループ分離キャラクター(←)
1E RS レコード分離キャラクター(↑)
1F US ユニット分離キャラクター(↓)
20 SPC 間隔・空白
7F DEL 削除

3.3 ISO 646

 ASCIIはアメリカ人に都合良く出来ています。しかし、コンピュータが世界中に普及すると、各国からその国独自の文字を使いたいという要望が出てきました。これに対応するのが、国際規格のISO 646です。ISO 646はASCII文字94文字のうち83文字をBCT(Basic Code Table)として各国で共通して使い、残りの12文字をIRV(International Reference Version)として、各国が好きな文字を使うことができることとしました。これにより各国版のISO 646が乱立することとなりました。

00 10 20 30 40 50 60 70
00 NUL DLE SP 0 @ P ` p
01 SOH DC1 ! 1 A Q a q
02 STX DC2 " 2 B R b r
03 ETX DC3 # 3 C S c s
04 EOT DC4 $ 4 D T d t
05 ENQ NAK % 5 E U e u
06 ACK SYN & 6 F V f v
07 BEL ETB ' 7 G W g w
08 BS CAN ( 8 H X h x
09 HT EM ) 9 I Y i y
0A LF SUB * : J Z j z
0B VT ESC + ; K [ k {
0C FF FS , < L \ l |
0D CR GS - = M ] m }
0E SO RS . > N ^ n ~
0F SI US / ? O _ o DEL

 各国で自由に使っていいIRVは0x23、0x24、0x40、0x5B、0x5C、0x5D、0x5E、0x60、0x7B、0x7C、0x7D、0x7Eの12です。各国が定めた12文字は次の通りです。背景色を赤にしてある文字が各国が独自に定めた文字です。

国名 アメリカ 日本 イギリス フランス ドイツ スウェーデン スペイン
0x23 # # £ # # # #
0x24 $ $ $ $ $ ¤ $
0x40 @ @ @ Á § É ·
0x5B [ [ [ ° Ä Ä ¡
0x5C \ \ \ Ç Ö Ö Ñ
0x5D ] ] ] § Ü Å Ç
0x5E ^ ^ ^ ^ ^ Ü ¿
0x60 ` ` ` µ ` é `
0x7B { { { é ä ä '
0x7C | | | ú ö ö ñ
0x7D } } } é ü å ç
0x7E ~ ¯ ~ ¨ ß ü ¨

※各国の規格名称;アメリカ:US-ASCII、日本:JIS X 0201 Roman、イギリス:BS 4730、フランス:NF Z 62-010-1982、ドイツ:DIN 66 003、スウェーデン:SEN 85 02 00 Annex C、スペイン:IBM Spanish
※ISO(国際標準化機構、International Organization for Standard)は国際的な標準である国際規格を策定するための非政府組織です。

3.4 8bit拡張

 ISO 646では高々12文字しか自由にできないので、各国には不満が残りました。しかも、ASCIIとの互換性が失われてしまいます。特に#や{を多用しているプログラミング言語は、困ったことになりました。そこで、ASCIIコードはそのまま利用して、別の手段を考えようということになりました。

 現代のコンピュータは殆ど1バイト単位(8ビット)単位でデータを扱うため、1文字を7ビットではなく、8ビットで扱うのが都合がいいということは説明するまでもなく理解していただけると思います。1文字8ビットで扱うことにすると、ASCIIの0x80~0xFFの部分はまだ空いています。とりあえずこの部分に必要な文字を押し込めばいいということになります。

 そこで、0x00~0x7Fまでの下位領域はASCIIと同じで、0x80~0xFFに大手コンピュータメーカや、各国の標準化団体などが自社や、自国の必要な独自文字を収録したASCII互換の拡張文字コードを規格化することになりました。これがISO 8859です。これはISO 8859-1((Latin-1)(ラテン文字・西欧)から8859-10(Latin-6)(ラテン文字・北欧)の10種類があります。
ISO-8859 文字・言語・地域
1 ラテン文字・西欧(Latin-1)
2 ラテン文字・東欧(Latin-2)
3 ラテン文字・エスペラント(Latin-3)
4 ラテン文字・北欧(Latin-4)
5 キリル文字 ロシア語
6 アラビア文字 アラビア語
7 ギリシャ文字 ギリシャ語
8 ヘブライ文字 ヘブライ語
9 ラテン文字・西欧+トルコ語(Latin-5)
10 ラテン文字 北欧(Latin-6)

3.5 日本の1バイト文字集合

 日本での1バイト文字集合は「7ビット及び8ビットの情報交換用符号化文字集合」(JIS X 0201)といいます。7ビットなのか8ビットなのかといいたくなりますが、どっちでも使えます。

 JIS X 0201はASCII文字集合をベースにしたラテン文字用の文字集合と、カタカナ用の文字集合の二つの文字集合で構成されています。

 ラテン文字用の文字集合はISO/IEC 646のJP版と同じです。

 8ビット符号では、0x21~0x7Eにラテン文字を、0xA1~0xDFにカタカナを割り当てています。7ビットで使う場合は、SHIFT-INとSHIFT-OUTを使って、0x21~0x7Eの領域をラテン文字とカタカナで使い分けます。この場合、カタカナの0x60~0x7E部分は空白文字が割り当てられます。じ

※SHIFT-IN(SI)は0x0F、SHIFT-OUT(SO)は0x0Eで示します。

00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
00 0 @ P ` p
01 ! 1 A Q a q
02 " 2 B R b r
03 # 3 C S c s
04 $ 4 D T d t
05 % 5 E U e u
06 & 6 F V f v
07 ' 7 G W g w
08 ( 8 H X h x
09 ) 9 I Y i y
0A * : J Z j z
0B + ; K [ k {
0C , < L \ l |
0D - = M ] m }
0E . > N ^ n ¯
0F / ? O _ o

※JIS X 0201は当初はJIS C 6220 と呼ばれていましたが、JISに情報部門の分類「X」が新たに制定されたために以後は、JIS X 0201と呼ばれています。

 0xA1~0xDFの半角カタカナは全角表示しています。

 JISでは制御文字の部分はJIS X 0211で規定しています。JIS X 0211の制御コードにはC0集合とC1集合があり、C0集合はASCIIの0x00~0x1Fに対応しています。C1集合はそれ以外の制御コードになります。それから、JIS X 0211には0x20のSP(スペース)と0x7Fの(DEL、delete、削除)が含まれていません。

 一般的な実装としては、JIS X 0211(ISO/IEC 6429)制御文字集合の0x00~0x1Fと0x20、0x7FとJIS X 0201を組み合わせて使用します(0x20と、0x7FはJIS X 0201には含まれていません)。

00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
00 NUL DLE SP 0 @ P ` p
01 SOH DC1 ! 1 A Q a q
02 STX DC2 " 2 B R b r
03 ETX DC3 # 3 C S c s
04 EOT DC4 $ 4 D T d t
05 ENQ NAK % 5 E U e u
06 ACK SYN & 6 F V f v
07 BEL ETB ' 7 G W g w
08 BS CAN ( 8 H X h x
09 HT EM ) 9 I Y i y
0A LF SUB * : J Z j z
0B VT ESC + ; K [ k {
0C FF FS , < L \ l |
0D CR GS - = M ] m }
0E SO RS . > N ^ n ¯
0F SI US / ? O _ o DEL

 欧米では1バイト(8ビット)でも足りるかもしれませんが、日本や中国などでは1バイトでは全く足りません。

3.6 ISO-2022-JP

 ISO-2022-JPはISO-2022の仕組みに則って(ISO-2022のサブセットとして)定義された日本語の文字コードで通称は「JISコード」です。エスケープシーケンスという特殊な制御文字を挿入することで、複数の文字集合の切り替えを行います。

切り替え文字 切り替えコード 文字コード 意味
ESC $ @ 1B 24 40 JIS C 6226-1978(旧JIS78) 2バイト文字(JIS C 6226-1978)への切り替え
ESC $ B 1B 24 42 JIS X 0208-1983(新JIS83) 2バイト文字(JIS X 0208-1983)への切り替え
ESC & @ ESC $ B 1B 26 40 1B 24 42 JIS X 0208-1990(JIS90) 2バイト文字(JIS X 0208-1990)への切り替え
ESC ( B 1B 28 42 ASCII 1バイト文字(ASCII)への切り替え 
ESC ( J 1B 28 4A JISローマ字 1バイト文字(JISローマ字)への切り替え
ESC ( I 1B 28 49 JIS X 0201の半角カタカナ 1バイト文字(JIS X 0201の半角カタカナ)への切り替え

※[ESC]はエスケープ文字といいます。コード切り替えのための制御文字は、このエスケープ文字に続く一連の(sequence)制御文字ですので、エスケープシーケンスと呼ばれます。

 日本語には大量の漢字がありますので、これをどのようにコード化するかが重要になります。漢字は何万とありますので、これをどのようにコード化するかですが、1バイトでは256通りの文字しか扱えませんので、とても無理です。そこで導入されたのが2バイトを使うという方法です。2バイトあれば256×256=65,536個の文字を扱うことができます。この漢字を含む文字コードは通常漢字コードと呼ばれます。

 では漢字コードは1種類かというとそうではありません。漢字でもよく使うものから、ほとんど使わないもの、専門家が使うもの、特定の業界で使用する特殊な文字など様々です。人名にしか使わないようなものなどもあります。これを全部ひっくるめて一緒に扱うのは余り得策ではありません。特にコンピュータで扱う場合には、記憶容量の問題等にもかかわってきます。そこで、日本工業規格では漢字を使用頻度などを基準として、第1水準、第2水準、第3水準、第4水準、補助漢字などに分けています。第1水準と第2水準は日常的に使用する重要漢字を集めたものです。第1水準は2965字で、常用漢字1945字と人名用漢字が含まれています。通常の文書であれば第1水準だけで記述できるとされています。第2水準は3390字で、印刷などで利用するフォントの多くはJIS第1水準、第2水準を網羅しているとされます。JIS第3水準と第4水準は、業種によって必要となる特殊な記号などを集めています。この他に、補助漢字なども定められています。

 これらの漢字のうち、第1水準、第2水準だけに絞ったもの、補助漢字だけに限定したものなどというように分類して規格化しています。代表的なコードがJIS X 0208です(通称はJIS漢字コード)。

JIS X 0208

 JIS X 0208の文字を表すことのできる領域は256×256=65,536あります。上の表の1つの升目は16×16=256の文字が入りますので、ASCII文字はこの升目の半分に収まります。表の中に色を付けた部分がJIS X 0208が利用している漢字コードの領域です。漢字コードといっても仮名やカタカナなども入っています。第1バイトが21~28、第2バイト21~7Eの領域に記号等の特殊文字147文字、数字10文字、ローマ字52文字、平仮名83文字、カタカナ86文字、ギリシャ文字48文字、ロシア(キリル)文字66文字、罫線素片32文字が入っています。それから、第1バイト30~4F、第2バイト21~7Eの間に第一水準漢字2,965文字、第一バイト50~74、第2バイト21~7Eの領域に第二水準漢字3,390文字が収められています。例えば、0x3021=「亜」、0x3022=「唖」、0x3023=「娃」、0x3024=「阿」というように文字が格納されています。従って、0x3021と指定すれば、「亜」という漢字を取り出すことができるということになります。「細」=0x3A59ですので、0x30213A593021で「亜細亜」という文字列になります。

※JISのコード表はASCIIと上位ビット、下位ビットの位置が入れ替わっていることに注意してください。

 日本工業規格で定められたものには、JIS X 0208、JIS X 0212、JIS X 0213、JIS X 0221などがあります。

JISコード名 規定の範囲 通称 備考
JIS X 0208 第1水準、第2水準漢字、非漢字 JIS78 1978年制定のJIS C 6226-1978(JIS X 0208-1978)
JIS83 1983年制定のJIS C 6226-1983(JIS X 0208-1983)
JIS90 1990年制定のJIS X 0208-1990
JIS97 1997年制定のJIS X 0208:1997(基本的にはJIS90と同じ)
JIS X 0212 補助漢字、非漢字
JIS X 0213 第1~第4水準、非漢字 JIS2000 2000年に制定されたJIS X 0213:2000
JIS2004 2004年に制定されたJIS X 0213:2004
JIS X 0221    国際符号化文字集合    UNICODE1.1 1995年制定のJIS X 0221-1995。対応するのはISO/IEC 10646-1:1993(1993年制定)
 UNICODE3.0 2001年制定のJIS X 0221:2001。対応するのはISO/IEC 10646-1:2000(2000年改訂) 
 UNICODE5.0 2007年制定のJIS X 0221:2007。対応するのはISO/IEC 10646:2003(2003年制定)  
 UNICODE6.1 2014年制定のJIS X 0221:2014。対応するのはISO/IEC 10646:2012(2012年改訂)  

※JIS C 6226-1978、JIS C 6226-1983は87年にJISに情報部門(分類記号「X」)が新たに制定されたため以後はJIS X 0208-1978、JIS X 0208-1983と呼ばれています。
※JIS X 0208-1990とJIS X 0208:1997は基本的には同じ内容です。ISOと表記形式を一致させるために、制定年表記の前を「-」から、「:」に変更しました。

 これらの規格をISOの規格に取り込んだのがISO-2022-JPです。文字の集合としては、日本で使われている漢字、ひらがな、カタカナはもちろん、ラテン文字、ギリシャ文字、キリル文字などが含まれます。ISO-2022-JPに含まれるのは、JIS X 0211のC0集合(制御文字)、JIS X 0201のラテン文字集合、ISO 646の国際基準版図形文字、JIS X 0208の1978年版(JIS X 0208-1978)、1983年版(JIS X 0208-1983)、1990年版(JIS X 0208-1990)です。JIS X 0201のラテン文字集合の部分は使えますが、JIS X 0201の半角カタカナ文字の集合は利用できません。

 ISO-2022-JPを拡張して、ISO-2022-JPの文字集合に加えて、JIS X 0212を利用できるようにしたのが、ISO-2022-JP-1です。更に、JIS-0212、KS X 1001、GB 2312、ISO 8859-1、ISO 8859-7を利用できるようにしたものが、ISO-2022-JP-2です。更にJIS X 0208をJIS X 0213:2000に変更したのがISO-2022-JP-3です。JIS X 0213:2000をJIS X 0213:1004に置き換えたのが、ISO-2022-JP-2004です。

※KS(Korean Standard) X 1001は韓国でハングルや漢字を表すために使われる文字コード規格(以前の呼称はKS C 5601)、GB 2312(あるいはGB 2312-80、あるいはGB 2312-1980)は中華人民共和国の国家規格(GBは国家標準(Goja Byojun、ゴージャビョージュン)の意味)として規定された簡体字中国語の文字コード規格で、主として中国大陸で使用されています。

 このように様々な漢字コードがありますので、これを切り替えて使うためのエスケープシーケンスもこれに対応したものが予め定められています。

符号化文字集合 16進表現 文字列表現
1バイト文字から2バイト文字への切り替え JIS C 6226-1978(JIS X 0208-1978、旧JIS) 1B 24 40 ESC $ @
JIS C 6226-1983(JIS X 0208-1983、新JIS) 1B 24 42 ESC $ B
JIS X 0208-1990 1B 26 40 1B 24 42 ESC & @ $ B
JIS X 0212-1990(補助漢字) 1B 24 28 44 ESC $ ( D
JIS X 0213:2000
※第1、第2水準
1B 24 28 4F ESC $ ( O
JIS X 0213:2004
※第1、第2水準
1B 24 28 51 ESC $ ( Q
JIS X 0213:2000
※第3、第4水準
1B 24 28 50 ESC $ ( P
2バイト文字から1バイト文字への切り替え JIS X 0201-1976 Roman Set(半角英数) 1B 28 4A ESC ( J
JIS X 0201-1976 カタカナ 1B 28 49 ESC ( I
ISO/IEC 646 (ASCII) 1B 28 42 ESC ( B

 ISO-2022-JPでは、文章の途中だけ抜き出して、この文字がなんであるかを決定することができません。その抜き出した文章の先にあるエスケープシーケンスによって文字コードの意味が違ってしまうからです。従って、任意の行をコピーして、貼り付けるとエスケープシーケンスが付いてこないので文字化けを起こしてしまいます。そこで、「行の始まりはASCIIで始まる」「行の終わりは(改行の直前)はASCIIで終わる」という規則が定められています。これだと、行単位でのコピーができます。

 ISO-2022-JPを使うと、切り替え用のコードの分だけ、文書データの量が増えてしまいます。

 ISO-2022-JPは、インターネット上で日本の文字用の符号化方式として一般的に使われています。

 ISO-2022-JPを使うというなら、その仕様通りに使用しなくてはならないはずですが、符号化方式をISO-2022-JPと宣言しながら、実はJIS X 0212(補助漢字)や、JIS X 0201(いわゆる半角カナ)も符号化しているものなどがあります。中にはISO/IEC 2022の仕様にすら準拠していないものもあります。受信側のメールクライアントがこれらの独自拡張に対応していない場合は、その文字、あるいはその文字を含むテキスト全体が文字化けしてしまうことがあります。

3.7 MS漢字コード(シフトJISコード)

 MS-DOS、Windows、Macintoshなどで使用される漢字コードです。マイクロソフト社が提唱したもので、「MS漢字コード」とも呼ばれています。かつてはベンダー独自の拡張を含む曖昧な文字コードでしたが、現在はJIS X 0208の付属書1で規定されています。

※シフトJISはマイクロソフト、アスキー、三菱電機、マイクロソフト・アソシエイツ、デジタルリサーチの共同開発です。

 シフトJISの設計者は先行していたJIS C 6220(JIS X 0201)と、JIS C 6226(JIS X 0208)の両方の文字集合を、エスケープシーケンスなしに表現しようとしました。エスケープシーケンスを使うとファイルが大きくなってしまいますし、切り替え処理の時間も余計にかかるからです。

 1バイト文字のJIS X 0201と2バイト文字のJIS X 0208を混在させるとどうなるでしょうか。第1バイトが0x00~0x7Eまでの領域は、1バイト目がASCIIのコードと重なってしまうために使えません。残りの0x8000~0xFFFF部分を全部使えればいいのですが、その時既にJIS X 0201が普及し、半角カタカナで0xA1~0XDFの領域を使ってしまっていたので、第1バイトが0xA1~0xDFの領域も使えません。下の図で色を塗りつぶしている部分は使えないということになります。残っているのは白い部分だけです。ここにうまい具合に、かな・英数字等、第1水準漢字、第2水準漢字を押し込めたのがシフトJISというコードです。


 シフトJISは切り替え用のエスケープシーケンスを使いませんので、データ量も増えませんし、コードを切り替える処理に時間がかかるということもありません。1バイトを読み込んで0x00~0x7F、0xA1~0xDFなら1バイト文字です。0x80~0x9F、0xE0~0xEFならば2バイト文字ですので、続いてもう1バイト読み込んで、文字に変換するということになります。

 残された領域は余りありませんので、補助漢字なども定義することができません。

3.8 EUCコード

 EUC(Extended UNIX Code)は、UNIX系OSで標準的に使われる文字コードです。日本語だけでなく、1文字を1バイトで表現しきれない多バイト文字で使われています。日本語の文字を収録したものはEUC-JP、あるいは日本語EUCなどと呼び、韓国語はEUC-KR、簡体字中国語はEUC-CN、繁体字中国語はEUC-TWなどと呼びます。
 
 EUC-JPはEUCのエンコード方式上にASCIIとJIS X 0208文字集合を配置したものです。JIS X 0208はJIS X 0208:1990を使うものと、JIS X 0213:2004を使うものがあります。単にEUC-JPという場合は、前者を指すことが多く、後者を指す場合には、「EUC-JIS-2004」のように言うのが一般的です。前者は、JIS X 0208以外に、JIS X 0201のいわゆる半角カナやJIS X 0212の補助漢字を含むことができますが、これらはオプションで、実装されていない場合もあります。半角カナと補助漢字を使わない場合は、JIS X 0208で規定されているものと同じになります。

 EUC-JPではJIS x 0208の文字集合を上位バイト、下位バイトともに0x80移動したものです。従って日本語文字が上位バイトも下位バイトも0x80~0xFFの範囲内にあり(最上位ビットが”1”にセットされています)、日本語の区別が付け易くなっています(プログラミングをする際の扱いが便利です)。

 補助漢字を使う場合は、制御文字のSS3(Single Shift 3)(制御コードはJIS X 0211のC1集合の"0x8F")に続いて、補助漢字が現れるので、合計3バイトになります。

 半角カタカナは上位バイト0x8E、下位バイト0xA1~0xDFに収められています。

EUC-JP

3.9 UNICODE

 シフトJISは第1バイトが0xA0~0xD0の領域を使わないようにしています。ここは半角カタカナの部分と重なってしまうためです。ところが、EUC-JPは半角カタカナを上位バイト0x8E、下位バイト0xA1~0xDFに収めて、第1バイトが0xA0~0xD0の領域に別の文字を割り当ててしまっています。これは、EUC-JPという文字コードの範囲では、問題ないのですが、EUC-JPで書かれた文章を、シフトJISと勘違いしてしまうと文字化けが発生してしまいます。

※例えば、シフトJISでは1バイト文字に関してはJIS X 0201のコードをそのまま利用しています。そして、半角カタカナの「ア」「イ」(※全角で表示しています)は、「0xB1」「0xB2」となります。これがシフトJISだと分かっていれば何の問題もありませんが、何らかの理由で(例えば、EUC-JPで書かれた文章の中に、シフトJISで書かれた文章をcopy & pasteしたときなど)、EUC-JPで読み込んでしまうと、2バイト文字「0xB1B2」の「渦」と解釈されてしまいます。

 日本では、JISコード、シフトJIS、EUC-JPといろいろあり、それぞれアルファベット、数字、漢字などが混在した文章が書けるように配慮されいますので、英語と日本語が混じった文章でも問題なく書くことができ、文字化けなく表示できます。しかし、世界に目を向けると更にいろいろの文字コードが存在しています。日本語と、中国語が混じった文章や、日本語と韓国語が混じった文章、日本語とアラビア語が混在した文章などは書くことができません。これでは、これからの国際化の時代に対応できません。また、各国に対応したアプリケーションを開発しようとする企業の立場からは、それぞれの言語に対応するためのコストが膨大な額に膨らんでしまい、これを何とかしたいという要望が出てきます。

■UNICODEの誕生
 問題を解消する手段として、ゼロックス社は世界中の全ての文字を含んだ文字コードを作ることを提唱しました。全ての文字コードを含んでいますので、1つの文章の中に多言語を混在することができますし、文字化けの心配もありません。これがUNICODEの始まりで、Microsoft、Apple、IBMなどの企業が参加して、UNICODEコンソーシアムという組織が結成されました。

 最初は、16bitで世界中の文字を表そうとしました。今までの文字コードは1バイト文字と重複しないように、使用する領域を特定領域に限定していたために、使える範囲が限定されています。そのような限定をとってしまうと、216=256×256=65536の文字を表現することができます。ただ、UNICODEだと分からないといけないので、16進表示の前に"U+"と付けることになりました。これがUNICODE1.0です。

 これとは別にISOも世界の主要な文字を一括して扱う多言語文字セット規格を開発していましたが、複数の国際規格が制定されるのは非効率であるため両者が歩み寄る形で(実際はISOがUNICODEの規格に合わせる形での規格の変更を行いました)、Universal multi-octet coded Character Setが1993年に制定されました。これがISO/IEC 10646(≒UNICODE2.1)です。この規格の日本語版はJIS X 0221(JIS X 0221-1:2001国際符号化文字集合(UCS)-第1部:体系及び基本多言語面)として制定されています。

 しかし、16ビット(2バイト)で世界中の文字を表現しようなんて端から無理に決まっています(と言っては申し訳ないのですが)。中国の清の時代に編纂された「康煕字典」には5万字近い文字が収録されています。日本の「大漢和辞典」にも5万字位の漢字が載っています。これ以外にも漢字を使っている国としては朝鮮半島、ベトナム、台湾などがあります。16ビットではとても間に合いません。東洋人がこれほど多くの文字を駆使していることは西洋人には想像もできなかったようです。

 これらは全部中国の漢字がルーツですので、現在は表記が若干異なっていますが、意味的には同じ異体字が多くあります。16ビットの中に漢字を全部を押し込めようとするなら、ルーツが同じ漢字は1つの標準体だけで表現しなくてはならないということになります。これでは、各国の独自性が全く認められませんので、いろいろの国からこの文字を追加してくれ、あの文字も追加してくれと、どんどん要求が来て、結局16bitで世界中に文字を表現しようという野望はもろくも崩れ去るということになりました。

※UNICODE4.0の段階で16ビットで全ての文字を収録するという方針は捨てられました。ユニコードコンソーシアムは2014年6月16日に新しいバージンのUNICODE7.0の内容を発表しています。

 18ビット、19ビットだと容量的には使いやすいかもしれません。でも、コンピュータにはちょった扱いにくそうです。20ビットだと区切りが良さそうですが、これは人間から見てそう思うだけで、やはりコンピュータにとっては扱いにくい数です。今まで、ASCIIなどの1バイト文字、JIS漢字コードなどの2バイト文字を扱ってきたので、8ビット単位で扱うのが好都合です。8ビット、16ビットと来れば、次は24ビットかあるいは32ビットということになります。より扱いやすいのは32ビット(22×8=32)です。232=256×256×256×256=4294967296となりますので、40億個以上の文字を扱うことが可能です。これなら、文字がどんなにたくさんあっても大丈夫です。しかし、実際に普段使っている文字は16ビットで表現できて、これ以上の文字を使うことはめったにないのに、いつも32ビット分を使うのは余りにも無駄が多すぎます。

※ほとんど8ビットの文字で間に合う欧米の言語は、32ビット文字だと、データ量が4倍になってしまいます。日本語にしてもデータ量は2倍になります。

■サロゲートペア
 UNICODE1.0は16ビットですので65536通りの文字を割り当てることができますが、当然これで世界中の文字を割り当てることは無理だということは直ぐに分かりました。そこで、何らかの工夫が必要となります。UNICODEの開発者が考えたのが日本で使っているシフト(shift-)JISの工夫と全く同じです。シフトJISの工夫はASCII文字の範囲の0x00~0x7Fの文字が出現したら、そのまま1バイト文字として扱い、0x80~0xFFが現れたら、これは2バイト文字なので、もう1バイト読み込んで、2バイトの数値に対して、対応する文字を表示するというものです(※ただし、シフトJISの場合は半角カタカナへの配慮がありますので、若干異なりますが)。

 UNICODE1.0は65536通りのうち、0xD800~0xDFFFについては、文字を割り当てていません。従って、2048(=8×256)文字分の空きがあります。このうち、前半の1024文字分の0xD800~0xDBFFについてシフトJISと全く同様の工夫を施したのです。具体的にはこうなります。2バイトを読み込んで、0xD800~0xDBFFの範囲のいずれかの数値が出現したら、これは4バイト文字に対応するので、必ず4バイト読み込んでから、文字の表示をするようにしたのです。4バイト文字の3バイト目、4バイト目は0xDC00~0xDFFFが来るように工夫されています。これによって、1024×1024(=256×4×256×4)=1048576となり、表現できる文字が100万字にまで増えました。この2文字分で1文字を表現するペアのことをサロゲートペア(surrogate pair、代理対)と呼びます。

■UNICODEの文字表
 UNICODEは16ビットで全ての文字を収めようとしたのですが、UNICODEへの追加収録文字を検討する過程で、16ビットでは収まりきらないことが明確になったため、現在では21ビットに拡張されています。

 UNICODEの文字表は、16ビット時代のUNICODEで規定された文字表と、後のバージョンで拡張された部分に分けることができます。

 UCSの区分けの方式に従うと、文字表は群(group)・面(plane)・区(row)・点(cell)の4段階の構造を持っています。面が1つの表の単位で、各面は256区×256点で、65536文字分の升目(コードポイント)に区切られています。UCSでは更にこの上に0面~255面を単位とする群が128個定義されています

※区と点によって文字を指定する方式はJIS X 0208の規定などでも使われています。

 このうち最も基本となるのが0群0面の文字表で、基本多言語面(BMP:Basic Multilingual Plane)と呼ばれます。BMPはUNICODE開発当初の16ビット文字の表です。これ以外の文字については追加多言語面(SMP、Supplementary Multilingual Plane)と呼ばれています。

 BMP以外の追加収録文字は、別途表を作成して、第0群第1面~第16面までの範囲で定義されています。

 拡張領域はUNICODE3.1以降に割り当てられました。第1面は古代文字などが収録されています。第2面は日本の拡張漢字部分のCJK統合漢字拡張B、Cが収録されています。第14面は制御コードを収録する追加特殊用途面で、第15面、第16面は私用目的のための面と規定されています。今後は、第3面に金文や甲骨文などの漢字系の出土文字が収録される予定です。

■UNICODEのエンコーディング方式(スキーム)
 UNICODEは世界中の文字を数値(文字コード)に変えた際の数値(文字コード)自体を指します。UNICODEは当初は16ビットで全世界の文字を表そうとしたのですが、16ビットの中に全ての文字を押し込めるのは難しいので、いろいろの工夫をしたり、ビット数を増やしたりしました(現在21ビットまで拡張されています)。しかも、これを何度もの改定作業を経て決めていったので(現在も改訂作業中のようです)、必ずしもコンピュータには扱い易いものではありません。

 これをコンピュータに扱いやすいようにするための何らかの工夫が必要になります。この方法をエンコード方式といいます。コンピュータは8ビット単位のコードが扱いやすいので、UNICODEを8ビット単位に読み替えるUTF(UCS Transform Format)というエンコード方式が提案されました。

 何とか、コンピュータが扱いやすいようにということで提案されたUTFですが、このUTFにもいくつかの方法があります。

≪UTF-16≫
 BMP内の文字は16ビットで、それ以外のSMPに関しては、ザロゲートペアを使って32ビットで表現するという方式です。Windowsでワイド文字と言っているのがUTP-16です。

≪UTF-32≫
 ザロゲートペアは厄介なので全部32ビットで表現しようというのがUTF-32です。ただ、非常に無駄が多いので、あまり利用されていないようです。

≪UTF-8≫
 UTF-8はASCIIに相当する文字を1バイトで、その他の部分は2~4バイトで表します。この方式では、英字は8ビットで済みますので、英字が殆どの文章の場合は、UTF-16よりもずっと小さな容量となります。この方式では、ASCIIのコードをそのまま使うことができますので、これまで大量に作られてきた英文のドキュメントをそのまま使うことができるという利点もあります。ただし、この方法だと、漢字はBMPの部分は3バイト、拡張部分は4バイトになってしまい、シフトJISやUTF-16よりも1.5倍程度増加してしまいます。しかも、24ビットという数はコンピュータには扱いにくいという面がありますので、多分処理時間、負荷等の問題もあると思われます。

■BOM
 UNICODEという1つの方式だけで全部済まそうとしたのですが、結局UTF-8、UTF-16、UTF-32とかいろいろと出てきてしまいました。こうなると、UTF-8でエンコードされているのか、UTF-16でエンコードされているのか、それともUTF-32なのか分かりません。何か目印が必要になります。この目印を[BOM」(Bite Order Mark)といいます。

エンコード方式 BOM
UTF-8 EF BB BF
UTF-16 ビッグエンディアン FE FF
リトルエンディアン FF FE
UTF-32 ビッグエンディアン 00 00 FE FF
リトルエンディアン FF FE 00 00

※エンディアン(endianness)は多バイトのデータをバイト列に並べるための方法で、バイトオーダとも言います。リトルエンディアン(LE)は下位バイトから、ビッグエンディアンは上位バイトから、メモリの下位順位から順に格納していきます。ビッグエンディアンは人間にとっては分かり易いという利点がありますが、リトルエンディアンはメモリの下位番地に、下位バイトが格納されますので、論理的で、コンピュータにとっても処理しやすい手法と言えます。

※BOMは元々バイトオーダを見分ける指標として使われていたのですが、エンコードの方式を見分けることもできるので、使おうということになりました。

3.10 文字コードの変換

 今まで見てきたようにインターネットではJISコード系のISO-2022-JP、Windows、MacintoshではシフトJIS、UNIX系ではEUC-JPが使われています。WindowsのWORDで作成したファイルや、UNIX系のツールで作成したファイルをWeb上で公開したり、メールで転送したりすることもあります。また、Windows系で作成したファイルを、UNIX上で読みたいということもあるでしょう。そのためには、JISコードとシフトJIS、EUC-JPの間でコードの変換をしなくてはなりません。そのため、そのようなことを予め見越して、シフトJISや、EUC-JPは文字の領域を規則的に変換しています。

■JISコードとEUC-JPの間の変換
 EUC-JPはJIS X 0208が使っていた領域をそっくりそのまま、上位バイト、下位バイトともに0x80バイトだけ移動しています。

 JISコードでは0x3021=「亜」、0x3022=「唖」、0x3023=「娃」、0x3024=「阿」、0x3025=「哀」、0x3026=「愛」と並んでいます。これをEUC-JPコードに変換するには、上位バイト、下位バイトにそれぞれ0x80を加えます。上位バイトは、0x30+0x80=0xB0となります。下位バイトは0x21+0x80=0xA1となりますので、EUC-JPコードでは、0xB0A1=「亜」、0xB0A2=「唖」、0xB0A3=「娃」、0xB0A4=「阿」、0xB0A5=「哀」、0xB0A6=「愛」となります。

■JISコードとシフトJISコードの間の変換
 JIS X 0208の2バイトコードの領域は第1バイト0x21~0x7C、第2バイト0x21~0x7Eの領域にまとまっていますが、シフトJISではこれを2つの領域に分けて移動しています。

 では具体的に見てみましょう。JIS X 0208の第1バイトが0x21~0x5Eの領域が、シフトJISでは第1バイト0x81~0x9Fの領域に移動しています。JIS X 0208の第1バイトが0x5F~0x7Eの領域が、シフトJISでは第1バイト0xE0~0xEFの領域に移動しています。

 EUC-JPはJIS X 0208の第2バイトの範囲をそのままの幅で移動していますので、簡単です。しかし、シフトJISの場合は第2バイトの幅をそのままにすると、空いている領域に収まりきらないので、元々の正方形の領域を縦を1/2にして、横を2倍にしています。


 JIS X 0208とシフトJISのコード変換のポイントはシフトJISに変換したとき、0x7Fの列は空白になっていることです。次の図を見てください。JIS X 0208の第2バイト0x21~0x7Eの部分がシフトJISでは0x40~0xFCに広がっています。つまり、第1バイトが奇数の部分と第2バイトが偶数の部分を横につなげる形をとっています。このときシフトJISの領域の0x7Fの列が空白となっているということはどういうことでしょうか。

 
 
 第1バイトが奇数の場合は、第2バイトの0x21~0x5Fが、移動先の0x40~0x7Eの部分に並べられ、続いて空白が1文字分挿入され、その後に0x60~0x7Eの部分が移動先の0x80~0x9Eに並べられ、次いで空白を入れずに、第1バイトが偶数の行の0x21~0x7E部分が、移動先の0x9F~0xFCの部分に追加されるというように並べられています。


 この移動図に従ってJIS X 0208のコードをシフトJISのコードに変換する計算式を作ってみましょう。

第1バイトの計算 第1バイトが0x21~0x5Eの場合
(第1バイト-0x21)÷2+0x81
第1バイトが0x5F~0x7Eの場合
(第1バイト-0x5F)÷2+0xE0
第2バイトの計算 第1バイトが奇数 第2バイトが0x21~0x5Fの場合
(第2バイト-0x20)+0x3F
第2バイトが0x60~0x7Eの場合
(第2バイト-0x20)+0x40
第1バイトが偶数 (第2バイト-0x20)+0x9E
 
 第1バイトが奇数の場合に、第2バイトが0x21~0x5Fの場合と、0x60~0x7Eの場合に分けて、1文字分ずらしているのは、シフトした領域での第2バイトの0x7Eの部分の空白列が理由です。

 心配ですので少し確認作業をしてみましょう。

●≪第1バイトが偶数で、0x21~0x5Eの例≫
 JIS X 0208で0x3021の「亜」は第1バイトが0x21~0x5Eの範囲にあるので、移動先の第1バイトは(0x30-0x21)÷2+0x81=0x07+0x81=0x88となります。第2バイトは、第1バイトが偶数ですので、(0x21-0x20)+0x9E=0x9Fとなります。第1バイトと第2バイトを合わせると、移動先のコードは0x889Fとなります。

●≪第1バイトが偶数で、0x5F~0x7Eの例≫
 JIS X 0208で0x6840の「萱」は第1バイトが0x5F~0x5Eの範囲にあるので、移動先の第1バイトは(0x68-0x5F)÷2+0xE0=0x04+0xE4=0xE4となります。第2バイトは、第1バイトが偶数なので、(0x40-0x20)+0x9E=0xBEとなり、第1バイトと第2バイトを合わせると、0xE4BEとなります。

●≪第1バイトが奇数で、0x21~0x5Eで、第2バイトが0x21~0x5F≫
 JIS X 0208で0x3524の「汽」は、第1バイトが0x21~0x5Eの範囲にあるので、移動先の第1バイトは(0x35-0x21)÷2+0x81=0x0A+0x81=0x8Bとなります。第2バイトは、第1バイトが奇数で、第2バイトが0x21~0x5Fの範囲にありますので、(0x24-0x20)+0x3F=0x43となり、第1バイトと第2バイトを合わせると、0x8B43となります。

●≪第1バイトが奇数で、0x21~0x5Eで、第2バイトが0x60~0x7E≫
 JIS X 0208の0x3363の「潟」は、第1バイトが0x21~0x5Eなので、移動先の第1バイトは(0x33-0x21)÷2+0x81=0x09+0x81=0x8Aとなります。第2バイトは、第1バイトが奇数で、第2バイトが0x60~0x7Eなので、(0x63-0x20)+0x40=0x83となり、第1バイトと第2バイトを合わせて、0x8A83となります。

●≪第1バイトが奇数で、0x5F~0x7Eで、第2バイトが0x21~0x5F≫
 JIS X 0208の0x6D54の「輳」は、第1バイトが0x5F~0x7Eなので、移動先の第1バイトは(0x6D-0x5F)÷2+0xE0=0x07+0xE0=0xE7となります。第2バイトは、第1バイトが奇数で、第2バイトの範囲が0x21~0x5Fなので、(0x54-0x20)+0x3F=0x73となり、第1バイトと第2バイトを合わせると、0xE773

●≪第1バイトが奇数で、0x5F~0x7Eで、第2バイトが0x60~0x7E≫
 JIS X 0208の0x6D70の「逅」は、第1バイトが0x5F~0x7Eなので、移動先の第1バイトは(0x6D-0x5F)÷2+0xE0=0x07+0xE0=0xE7となります。第2バイトは、第1バイトが奇数で、第2バイトが0x60~0x7Eなので、(0x70-0x20)+0x40=0x90となり、第1バイトと第2バイトを合わせて、0xE790となります。

以上の確認作業の結果、上の変換式で問題ないことが確認できました。皆さんも、JIS X 0208とシフトJISのコード表で、変換式を確認してみてください。

■UNICODEの変換
 UNICODEとJIS漢字コードや、シフトJIS、EUCの相互変換は複雑で、本書のレベルを超えますので、ここでは省略します。


4 データ圧縮

 データのサイズを小さくすることを「(データ)圧縮」といいます。小さく圧縮されたデータを元に戻すことは「解凍」とか 、「展開」といいます。

 初めになぜ圧縮の必要性があるかですが、データを圧縮するとハードディスク等のメモリの負担を軽減することができます。また、ネットワークの負荷も軽減することができます。近年のメモリの大容量化は目を見なるものがありますが、それを超える勢いでソフトウェアは肥大化しています。OSやアプリケーションが高性能化し、それに伴いソフトウェアの容量が増大し、また、画像・音声・動画などを扱うことが多くなったからです。これをこのまま放っておくと、メモリなどの資源がいくらあっても足りません。データを圧縮して保存するとデータの容量は驚くほど小さくなりディスクの容量を大幅に節約できるとともに、ネットワークの負担を軽減することができます。

 では、どうやってデータを圧縮するかですが、これには様々な方法があり、多くは高度の数学理論を駆使して行われますので、「情報科学の基本」をテーマとする本書のレベルをはるかに超えてしまいます。本書では分かり易いレベルで、概略だけ説明するということになりますので、予めご了承ください。

4.1 ランレングス法

 圧縮の方法として一番基本的な方法がランレングス法です。ラン(run)とは途切れずに同じことが続くことです。データの場合は「0」が連続して続いたり、「1」が連続して続くこと、あるいはASCIIコードの特定文字に該当するコードが連続して続いたり、JISコードの特定文字に該当するコードが連続して続いたりということを指します。ランレングス(run-length)は同じことが何度起きたかということで、データを圧縮する方法です。

元のデータ AAAAAAAAABBBBBBCCCCDDDDD
圧縮後のデータ A9B6C4D5

 上の方式は単純に同じ文字が連続で出現したら、その文字と出現回数で連続的な文字列を置き換えているだけです。都合よく同じ文字列が連続している場合は効率的な圧縮が可能ですが、連続性が少ない場合は反って容量が増えてしまうことがあります。

 次は反ってデータ量が増えてしまう場合の例です。連続していないデータに関しても回数を入れると、データ量は増えてしまいます。

元のデータ AABCDEFGHHHIJKLMNNNNNOPR
圧縮後のデータ A2B1C1D1E1F1G1H3J1J1K1L1M1N5O1P1R1

 同じ行の前後では同一性がない場合でも、前の行の同じ列との間に同一性がある場合もあります。このような場合は前の行のデータとの関係で予測を立て、その予測と結果のデータとの差分をとって、それにランレングス法を適用するという方法もあり得ます。

 次は、白と黒の画素の並びの例です。白は分かり易いように若干着色しています。

 原信号1 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4
原信号2                                          
原信号2の予測                                           
予測評価                                           
 原信号の2行目を予測して、予測が外れたら黒、当たったら白とすると、上の予測評価は「白2黒1白4黒1白1黒1白4黒1白2黒1白3」となります。予測があまり当たらないとデータ量が増えてしまいます。次は予測がよく当たった場合です。

原信号1 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4
原信号2
原信号2の予測
予測評価

 信号順序を入れ替えてしまう方法もあります。

  0 1 2 3 4 5 6 7 8 9 a b c d e f
系列1
系列2

2 3 4 8 9 a e f 0 1 5 6 7 b c d
系列3

 上の例の系列3は、系列1で黒だったセルを集めて、その後白だったセルを並べています。そこで系列2の結果を系列3の順に入れ込んでいくと、上のようになります。これも場合によっては圧縮率が高くなることがあります。

 上の例は白と黒の2通りの情報だけを処理するのでファクシミリー等に利用できます。次に、CG画像などを対象とする方法を紹介します。2次元で同色領域のランレングスを考えます(ストラクチャランレングス符号化法)。

 この方法は画素そのもののラン(run)を用いるのではなく、画素と画素の関係のランを用いています。この符号化法では、初めに原画像の画素を次の4つの場合に分類します。
U) 直ぐ上の画素と同色の場合
L) すぐ左の画素と同色の場合
S) 直ぐ右上の画素と同色の場合
N) それ以外の場合

 ここで2個以上の条件を同時に満たす場合は、U > L > S の順で優先順位をつけて場合分けをします。この符号法の走査では1スキャン分のバッファを持ち、操作処理の結果を保存します。分類の結果は4通りですので、2ビットで表現できます。

N L L L L N L L L L L L N L L L
U U U U S U U U U U N S U U U U
U U U U U U U U U U U U N L L L
U U U S U U U U U U U U U U U U
U U U U U U U U U U U U U U U U
U U U L L L L L L L U U U U U U
U U U U U U U U U U U U U U U U
U U U U U U U U N L L L U U U U

 この分類結果を用いて画像の符号化を行うと、複合の際にU、L、Sは周辺の画素の色を参照することで原画像を復元できますが、Nはうまくいきません。Nが少ないと効果的な圧縮が可能ですが、Nが多くなると、圧縮効果が上がりません。分類結果にランレングスを適用すると、UとLは長くなる傾向にあり、SとNは長いレングスを持つことは殆どありません。以上の結果、UとLにランレングスを適用すると、高い圧縮効果が期待できます。

4.2 ハフマン符号

 ランレングス法と並んで、データ圧縮の基本となるのがハフマン符号です。ハフマン符号は出現確率の高い文字、あるいは発生確率の高いランレングス数に対して、短い符号を割り当てる方式です。

発生確率 ハフマン符号
A 0.45 0.45 1 1
0.55 0
0.34 0
0.21 1
B 0.19 0.19 0 000
C 0.15 0.15 1 001
0.21
D 0.1 0.1 1 011
0.11 0
E 0.07 0.07 0 0100
0.04 1
F 0.03 0 01010
G 0.01 1 01011

 上の例では、発生確率の低い順に並べて、最も発生確率の低いものに「1」、その次に低いものに「0」というビットを割り当てています。更に、この2つの発生確率を加えて、その結果と、他の発生確率を比較して、最も低いものに「1」を、その次に低いものに「0」を割り当てるという作業を、順次行っています。このように発生確率や発生頻度によって符号の長さを変える方法を可変長符号といいます。

 この表はちょっと分かりにくいという人は次の二分木をご覧ください。理屈は上の表と同じです。


 ツリーの節(ノード)に割り当てられたビットを上から各文字まで読んでくると、その文字に割り当てられたビット列が分かります。例えば、E=0.07に対しては0100というビットが割り当てられます。

 二分木を採用していますので、各データに割り当てられたビット列は問題なく復号できます。例えば、B=00、C=001とすると、001は「001=C」を求める前に、00でBにマッチしてしまい、読み取られずに残った「1」は、その後のマッチングの対象となり、これ以降の復号は全く出来なくなってしまいます。ハフマン符号は二分木構造を採用していますので、このようなことは起こりません。

 ハフマン符号では発生確率の高いもの順に、あるいは発生頻度順に短いビット列を割り当てますので、効率的な圧縮が可能です。

 ハフマン符号やランレングス符号などは多くの圧縮技術の基礎部分で使用されています。ハフマン符号やランレングス符号などは、圧縮しても、元と全く同じものを正確に復元することができます。このような圧縮を可逆圧縮といいます。

 画像の圧縮技術として有名なJPEGなども基礎的な部分でランレングス法、ハフマン符号を利用していますが、JPEGは圧縮率を高めるために、ランレングス法、ハフマン符号を適用する前に、様々な複雑な情報カット技術を使っています。そのため、圧縮データを正確に元に戻すことができません。このような圧縮技術を不可逆圧縮といいます。

4.3 音声・画像・動画圧縮の基本原理

 データ圧縮の基本原理として、ランレングス法と、ハフマン符号について簡単に説明しましたが、音声データ、画像データ、動画データの圧縮では、ランレングス法やハフマン符号だけでなく、人間の聴覚や、視覚の特徴や、データそのものの特徴などをうまく捉えて圧縮を実現しています。


特徴 利用原理・技術
画像の性質を利用 2値画像 白黒の画素が連続しやすい ランレングス符号化
静止画 近くの画素は似ている ランレングス符号化、離散コサイン変換
動画 現画面は前画面に似ている 動き補正予測、双方向予測
人間の特性を利用 画像 色信号の変化には鈍感 人間の視覚で識別できないレベルで色情報を捨てる
音声 人間の聴覚は周波数によって感度が異なる(等ラウドネス曲線)、
大きな音と一緒に存在する小さな音は聞こえにくい
人間の耳に聞こえない音をカット、マスキング効果
符号の発生確率の偏りを利用 発生確率に偏りがある 可変長符号化等

■ 離散コサイン変換(DTC、discrete cosine transform)
 音声や画像(静止画)、動画(映像)の圧縮で利用される関数変換の手法が離散コサイン変換です。画像の圧縮では、人間の目にはあまり感じない、細かいところを削り取るというのが一般的な考え方です。この方法を実現するためにJPEG/MPEGがとった方法が画像を波形として捉えるという方法です。白黒の画像はx-y座標上の各点に輝度の情報をプロットしたものとみることができます。すると輝度の情報は、輝度=f(x、y)と表現することができます。色の情報についても同様に考えることができます。これが画像領域の情報です。これに離散コサイン変換を施すと、x軸方向の空間周波数と、y軸方向の空間周波数をそれぞれ座標軸とし(周波数領域)、座標上の点に各周波数の振幅(DCTの係数)をプロットした空間グラフが出来上がります。

※離散コサイン変換を自力で勉強したいという人は、大学の教養課程レベルの線形代数、微分積分を学び、その後、複素関数を学んで、その後フーリエ解析を学んで、このフーリエ解析の応用として学ぶ必要があります。

4.4 音声データ圧縮

 現在はPCM以外に様々なデジタル化の手法が開発されています。代表的なものはMP3ですが、その他にATRAC、ACC、WMAなどがあります。これらは全て、音声圧縮フォーマットです。

 音声圧縮フォーマットをまとめると次のようになります。

通称 正式名称 規格策定 リリース 主な利用機器
ATRAC Adaptive Transform Acoustic Coding Sony独自仕様 1992 MiniDisc、Sony製品等
MP3 MPEG-1 Audio Layer Ⅲ MPEG-1 Part 3、MPEG-2 Part 3 1993 MP3プレイヤー、iPod、iTunes、他
AAC Advanced Audio Coding MPEG-2 Part 7、MPEG-4 Part 3 1997 iTunes、iTunes Store、ワンセグ放送、他
WMA Windows Media Audio Microsoft独自仕様 1999 Windows Media Player、Microsoft製品等

 音声圧縮のフォーマットは様々なものがありますが、基本的な原理はほとんど同じです。圧縮フォーマットでは人間の聴覚の特徴をとらえて、人間の耳には聞こえない音は省いてしまうという方法で圧縮をしています。

 人間の聴覚は周波数によって感度が異なるために物理的に同じ音圧であっても周波数によって感じる音の大きさが大きく異なります。

 音のエネルギーが同じ場合、例えば同じ40dB(decibel、デシベル)の場合、高音(高周波数)の40dBと低音(低周波数)の40dBでは物理的には同じエネルギーですので、同じ音量に聞こえるはずですが、人に耳にはそのようには聞こえません。人の耳には、音の周波数によって音量の感じ方が大きく異なります。

 一定の音量音の1000Hz(1kHz)の音と、人間の耳に同じ音量に感じる値(音量)を周波数ごとに調べて結んだ曲線を「等ラウドネス曲線」(聴感曲線)といいます。例えば、1000Hzの時の80dBと同じに聞こえる音量(聴覚的に同じ音量)を周波数ごとに調べてその点をグラフにプロットし、それらの点を結んだものが等ラウドネス曲線です。つまり、500Hzの時はどの程度か、250Hzの時はどの程度かというように調べていって、それを曲線状に結ぶと等ラウドネス曲線が引けます。この音の聴覚的な強さのレベルをホーン(phon)といいます。

 等ラウドネス曲線を次に示します。

出展:国立研究開発法人 産業技術総合研究所のHPより
ISO 226 2003

 このグラフを見ると、人間は3000Hz~4000Hz当たりの音を最も敏感に感じることが分かります。これに対して低い周波数の音に対しては鈍感です。1000Hzの40dBと、125Hzの60dBが大体同じ程度に感じられることが分かります。

 それでは音声圧縮の大まかな手順を説明します。
 初めにPCMで使用したサンプリングの手法を使って、音声の曲線グラフから棒グラフを導きます。

≪ステップ1≫ 人間の耳に聞こえないレベルの音をカット
 等ラウドネス曲線を使って人間の耳に聞こえないレベルの音をカットします。上の等ラウドネス曲線の一番下の曲線がしきい値の曲線です。これよりも小さい音はどうせ人間に耳に聞こえないのでカットします。


≪ステップ2≫マスキング効果で聞こえなくなる音を更にカット
 人間の耳には、大きな音の近くの小さな音は聞こえにくいという特性を持っています。大きな音の直後の音はもちろん直前の音も聞こえません。このような現象をマスキング効果と呼びます。大きな音と小さな音の周波数が近いほどマスキング効果は大きくなります。

 マスキング効果によって聞こえなくなる音を省いても、聴感上はほとんど変わりないのでこれもカットしてしまいます。


 この他にも2つの音が同時に発生して、一方が他方にマスクされる場合もあります(同時マスキング)。これを周波数マスキングとも言います。また、音色によっても他の音をマスクする度合いが異なります。

≪ステップ3≫数学的に圧縮
 ステップ1、2は人間の聴覚の特質をとらえて聞こえない音をカットするという経験則に基づく方法でデータ量を圧縮する方法を採用しましたが、更に数学的な方法で圧縮する方法が採用されます。

■ 可逆圧縮と不可逆圧縮
 MP3、ATRAC、AAC、WMAの何れも不可逆方式です。不可逆圧縮方式ではデータの量は10分の1程度までデータを圧縮することができます。これに対して「可逆圧縮」方式では、人間の耳に聞こえないものでも、元に戻すために必要なものは捨てることができませんので、圧縮率はせいぜい2分の1程度です。

4.5 画像データの圧縮

 データ圧縮は似たような情報があれば一緒にしてしまうという方法ですので、データの種類が少ないほど効率的に行うことができます。グラフや、図、あるいはファクシミリのような白黒画像などには有効です。しかし、カラー画像のようにいろいろの色がある場合、例えばフルカラーで1677万色(256×256×256)もの色が使われると、なかなか同じ色が連続することがありません。このような場合でも圧縮しようとすると、人間の視覚では検知できないような微妙な違いや特徴を切り落としてしまうわざるを得ません。こうすると、元々の画像よりも画質が落ちてしまいますが、データ量は大幅に小さくすることができます。しかし、元の状態に再構成することはできなくなります。

 画像データのフォーマット形式としては、BMP、TIFF、PNM、PNG、JPEG、GIFなどがあります。BMP、TIFF、PNMは非圧縮データで、PNG、GIF、JPEGが圧縮方式です。


可逆/不可逆 フォーマット 備考
圧縮 可逆 GIF パソコン通信での画像交換用に開発されました。可逆圧縮ですので、完璧に元通りの画質の戻すことができます。256色を扱うことができます。ただし、元の画像が256色以上を使っている場合は、GIFフォーマットに適合するように減色する必要がありますので、このような場合には正確に元の画像に戻すことはできません。
PNG GIFと同様に可逆圧縮を採用しています。
不可逆 JPEG 今日、最も一般的な画像フォーマットです。圧縮率が高く、画質の低下も気づかないほどです。不可逆画像ですので、画像を保存する度に画質が低下します。オリジナルデータは可逆圧縮フォーマットを使用しているソフト(TIFやPhotoshopのPSD)で保存しておく方がいいかもしれません。

■ GIF(Graphics Interchange Format)
 GIFはランレングスやハフマン符号を使ってデータを圧縮しています。扱うことのできる色は最大で8ビット(256色)です。256色以上必要ないロゴや、アイコン、アニメ調のイラストなど、特に単色ベタ面を多く含む平坦な画像に向いていますが、写真などの多くの色数を必要とする画像には向いていません。

 GIFの特徴の一つはアニメーションにできることです。GIFアニメはコマ画像をパラパラ漫画の要領で表示させることで実現しています。

※GIFに使われているLZWという圧縮技術は米国のUnisys社が特許を保有していましたが、現在は期限切れになっています。

■ JPEG(Joint Photograph Experts Group)
 JPEGは24ビット(1670万色)まで扱うことができますので、多くの色数を必要とする写真などの表現に向いています。また、グラデーションなどの処理にも適していますが、アイコンやアニメ調の平坦なイラストなどの保存には向いていません(平坦の色の部分がにじんできたない印象の色になってしまいます)。

 JPEGは「明るさの変化に比較して、色調の変化には比較的鈍感である」という人間の目の性質を利用して、人間の目に気づかない程度に色調変化の部分のデータを捨ててしまうことで、データの圧縮を実現しています。データを捨てることで圧縮していますので、圧縮したデータは元に戻すことができません。

8×8ピクセル毎にDCTで処理

 JPEGでは情報を圧縮するために離散コサイン変換(DCT)を行います。DCTは画像領域の8×8ピクセル毎に適用します。処理の結果、周波数領域の情報が得られます。得られる情報は次のようなマトリックスの情報です。縦と横は周波数で、中のデータは周波数ごとの振幅値です(ただし数値は適当です)。左上が低周波数成分、右下が高周波数成分です。

水平方向の空間周波数 
垂直方向の空間周波数 298 56 32 16 9 6 4 3
145 ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ ・・・
67
30
10
8
5
3

 離散コサイン変換後の信号の周波数成分は低周波数領域に集中します。このデータを量子化して符号化しますが、その際に情報の集中していない領域に対して長い符号を割り当てるとか、0に近似して切り捨てるなどの手法で情報を圧縮します。

■ PNG(Portable Network Graphic、通称は「ピング」)
 特許問題があり使いにくかったGIFに代わるべきものとして開発された形式です。フルカラーでも8ビットからでも使うことができます。GIFと同様に可逆性の画像形式ですので、元に戻すことができます。GIFよりも10%~30%圧縮率がいいとされています。

 PNGは比較的新しく開発された優れた画像形式ですが、GIFと違ってアニメーションにすることはできません。また、フルカラーにすると、JPEGよりもファイルサイズが大きくなってしまうという欠点もあります。

4.6 動画データの圧縮

 動画(映像)のデータは一連の静止画フレームからなります。動画の圧縮にはこの静止画を圧縮する技術に加えて、一連の静止画の時系列の圧縮技法を組み合わせます。

 動画は静止画の連続として表現されます。人間の視覚に、連続して見えるためには、1秒間に30フレームの画像が必要と言われています。連続して撮影された映像では、この1/30秒間隔の2枚の静止画像の間には、何らかの相関性があります。

 連続した2つのフレームの間の相関性に着目したのがフレーム間予測(interframe prediction)です。2つのフレームは極めて似通っていることが通常ですので、前のフレームの値を使って次のフレーの画素値を予測し、その差分を情報として伝送します。

 映像の一部のみに動く物体が存在する場合は、このフレーム間予測技術は動き保証(motion compesation)と呼びます。動き保証では前フレームからの動きの差分情報だけを、動きベクトル(motion vector)として表現することで情報量を大幅に削減することができます。映像の一部に動く物体があり、その他の部分はほとんど動かないという場合は、非常に効率的に情報削減をすることができます。









更新履歴

2016/11/28              作成





















































































































ページの先頭