さて、今日はJIS X 0201について述べます。
 ASCIIがアメリカの規格機関(NGO)、ANSIによって制定されたアメリカで使う英数字および記号を盛り込んだ文字コードであるのに対し、JIS X 0201は日本の国家機関、JSAによって制定されたローマ字、数字、カタカナおよび記号を盛り込んだ文字コードです。

 7ビット方式と8ビット方式があります。

 7ビット方式は0x00〜0x7Fのコード表2枚があって、1枚はほとんどASCIIと同じJISラテン文字、もう1枚はカタカナのコード表を持っています。
 2枚のコード表が同じコードポイント(数字)を共有するため、同じ0x21というコードに「!」(感嘆符)という記号(ASCIIと同じ)と「。」(句点)という記号が割り当てられ、また、同じ0x5Fというコードに「_」(アンダースコア)という記号(ASCIIと同じ)と「゚」(半濁点)という記号が割り当てられます。

 2枚のコード表の切り替えにはSO(シフトアウト、0x0E)および文字コードとSI(シフトイン、0x0F)が使われます。
 デフォルトの状態ではJISラテン文字(ほとんどASCIIと同じ)で英数字になります。0x21が送られると感嘆符の意味になります。
 SOが来るとそこでコード表の切り替えが行われ、カタカナになります。0x21が送られると句点の意味になります。
 SIが来るとまたコード表の切り替えが行われ、英数字になります。
 このように、同じ文字コードで状態が切り替えられる文字コードをモードのある文字コードといいます。
 7ビット方式のJIS X 0201はモードがあり、文字コード表が2枚必要だが、7ビットで文字コードが収まるという特徴があります。

 8ビット方式のJIS X 0201は、1枚の文字コード表に全部の文字が収まります。
 0x00〜0x7Fの部分(左面)にはASCIIとほとんど同じJISラテン文字が、0x80〜0xFFの部分(右面)にはカタカナが入ります。
 7ビット方式のカタカナに0x80(1000 0000b)を足したものが8ビット方式のカタカナになります。
 8ビット方式のJIS X 0201にはモードがなく、文字コード表が1枚で済むが、8ビットの文字コードを必要とするという特徴があります。


20160219jis7

 上の図は、Windows用のエディターxyzzyで7ビット方式のJIS X 0201でファイルを作成したところです。
 下の画面はxdumpでダンプしたところです。右側の文字表示画面はShift_JIS表示ですが、8ビット方式のJIS X 0208と同じになっています。この理由はShift_JISを説明するときに説明します。
 xyzzyの左側の画面で表示されている文字コードと、xyzzyで表示されている文字、xdumpの右側で表示されている化け文字を表示するとこうなります。
 まず最初の「ABCDEアイウエオ(改行)」という行を調べます。

xyzzy表示 A B C D E (SO) (SI) (CR) (LF)
xdump16進 41 42 43 44 45 0E 31 32 33 34 35 0F 0D 0A
xdump文字 A B C D E . 1 2 3 4 5 . . .

 ABCDE部分は、xyzzy上も、xdumpの文字部分も等しく表示されています。

 そのあと、xyzzyでは何も表示されていませんが、xdumpの文字部分では「.」が表示されています。
 xdumpのコード部分を見ると、ここは制御文字(0x0E、SO)が入っています。
 これはカタカナコード表への切り替えを示す制御文字で、エディター上では見えないことが分かります。

 そのあと、xyzzyではアイウエオというカタカナが表示されていますが、xdumpの文字部分では「12345」が表示されています。
 xdumpのコード部分を見ると、ここは0x31 32 33 34 35で、ラテン文字としては12345、カタカナとしてはアイウエオであることが分かります。

 末尾に0x0D0A(CRLF)というWindowsの改行コードが入っていますが、その前に0x0Dが入っています。これは制御文字SIで、ふたたびJISラテン文字に戻ることを示します。

 次の行「!。_゚(改行)」(感嘆符、句点、アンダースコア、半濁点、改行)を調べます。

xyzzy表示 ! (SO) (SI) _ (SO) (SI) (CR) (LF)
xdump16進 21 0E 21 0F 5F 0E 5F 0F 0D 0A
3-1 ! . ! . _ . _ . . .

 これも、ラテン字の!、カタカナの。、ラテン字の_、カタカナの゚、改行の間に、SO、SI、SO、SIが挟まっています。
 ラテン字の!とカタカナの。は同じ0x21、ラテン字の_とカタカナの゚は同じ0x5Fです。

20160219jis8

 今度の図は、同じ文字列を8ビット方式のJIS X 0201で作ってダンプしたものです。
 今回はxdumpの右側(Shift_JIS表示)も文字化けが起こっていません。

 まず最初の「ABCDEアイウエオ(改行)」という行を調べます。

xyzzy表示 A B C D E (SO) (SI) (CR) (LF)
xdump16進 41 42 43 44 45 B1 B2 B3 B4 B5 0D 0A
xdump文字 A B C D E . .

 ABCDE部分も、アイウエオ部分も、xyzzy上も、xdumpの文字部分も等しく表示されています。制御文字0x0E、0x0Fがありません。
 xyzzyでアイウエオというカタカナが表示されている部分のxdumpのコード部分を見ると、ここは0xB1 B2 B3 B4 B5で、これはラテン文字の12345、0x31 32 33 34 35に0x80をそれぞれ加算していると分かります。
 末尾に0x0D0A(CRLF)というWindowsの改行コードが入っています。

 ASCII時代の、文字は7ビットで表現できる前提のシステムは7ビット方式が使われます。一方8ビット方式はSO/SIによるモード切替が不必要で、文字列の途中のどの部分を取ってもラテン文字かカタカナか瞬時に見分けられるという大きな利点があります。

 ASCIIとJISラテン文字は2つのコードポイントに違いがあります。
 1つは0x5Cで、ASCIIは\(バックスラッシュ)ですがJIS X 0201ラテン文字では¥(円記号)です。
 もう1つは0x7Eで、ASCIIは〜(チルダ)ですがJIS X 0201ラテン文字では ̄(上線)です。

 のちにJIS X 0208というひらがなや漢字も含む文字コードにおいても英数字やカタカナが二重に登録されたため、JIS X 0201のカタカナは半角カナ、JIS X 0201のカタカナは全角カナと言われます。逆にJIS X 0201の英数字は半角英数字、JIS X 0208の英数字は全角英数字と言われます。
 これは、JIS規格には文字幅が定義されていないので不正確であると言われますが、実用的にはこの言い方が幅広く認知されています。たとえば新生銀行のサイトとかに行くと「お名前は半角カナで入力してください」と堂々と言われます。

 JIS X 0201という文字コードの概要はこんな感じです。



 PerlでJIS X 0201はどのようにサポートされているでしょうか。
 まず、PerlのEncodeモジュールがサポートしている文字コードを一覧表示します。

#! /usr/local/bin/perl
# encode_list.pl -- サポートされているエンコードを一覧表示

use strict;
use warnings;
use 5.010;
use Encode;

say for sort Encode->encodings(":all");

 Encodeモジュールのencodingsメソッドに引数「:all」を渡すと、サポートしている全エンコードがリストで返りますので、これをsortして表示します。実行結果は以下の通りです。

[sample]$ ./encode_list.pl
7bit-jis
AdobeStandardEncoding
AdobeSymbol
AdobeZdingbat
MIME-B
MIME-Header
MIME-Header-ISO_2022_JP
MIME-Q
MacArabic
MacCentralEurRoman
MacChineseSimp
MacChineseTrad
MacCroatian
MacCyrillic
MacDingbats
MacFarsi
MacGreek
MacHebrew
MacIcelandic
MacJapanese
MacKorean
MacRoman
MacRomanian
MacRumanian
MacSami
MacSymbol
MacThai
MacTurkish
MacUkrainian
UCS-2BE
UCS-2LE
UTF-16
UTF-16BE
UTF-16LE
UTF-32
UTF-32BE
UTF-32LE
UTF-7
ascii
ascii-ctrl
big5-eten
big5-hkscs
cp1006
cp1026
cp1047
cp1250
cp1251
cp1252
cp1253
cp1254
cp1255
cp1256
cp1257
cp1258
cp37
cp424
cp437
cp500
cp737
cp775
cp850
cp852
cp855
cp856
cp857
cp858
cp860
cp861
cp862
cp863
cp864
cp865
cp866
cp869
cp874
cp875
cp932
cp936
cp949
cp950
dingbats
euc-cn
euc-jp
euc-kr
gb12345-raw
gb2312-raw
gsm0338
hp-roman8
hz
iso-2022-jp
iso-2022-jp-1
iso-2022-kr
iso-8859-1
iso-8859-10
iso-8859-11
iso-8859-13
iso-8859-14
iso-8859-15
iso-8859-16
iso-8859-2
iso-8859-3
iso-8859-4
iso-8859-5
iso-8859-6
iso-8859-7
iso-8859-8
iso-8859-9
iso-ir-165
jis0201-raw
jis0208-raw
jis0212-raw
johab
koi8-f
koi8-r
koi8-u
ksc5601-raw
nextstep
null
posix-bc
shiftjis
symbol
utf-8-strict
utf8
viscii

 アホみたいに出てきましたので、JISまたはjisを含むエンコード名だけに絞ります。

#! /usr/local/bin/perl
# encode_list_jis.pl -- サポートされているエンコードを一覧表示(JIS系のみ)

use strict;
use warnings;
use 5.010;
use Encode;

say for sort grep {/jis/i} Encode->encodings(":all");

[sample]$ ./encode_list_jis.pl
7bit-jis
jis0201-raw
jis0208-raw
jis0212-raw
shiftjis

 5つにしぼれましたね。このうちjis0208-rawというのはJIS X 0208、JIS X 0212-rawというのはJIS X 0212(補助漢字)、shiftjisはShift_JISに関係ありそうなので除外できます。
 まず、jis0201-rawというのを試します。

#! /usr/local/bin/perl
# test0201raw.pl -- jis0201-rawの実験

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(jis0201-raw)";

say "ABCDEアイウエオ";

 以下のようになります。

04
 このように、8ビット系のJIS X 0201を表示します。
 ちなみにEmacsエディターはShift_JISであると勘違いしています。

 では、7bit-jisを使ってみましょう。

#! /usr/local/bin/perl
# test0201raw.pl -- jis0201-rawの実験

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(jis0201-raw)";

say "ABCDEアイウエオ";

 以下のようになります。
34
 これは、ISO 2022の枠組みで、ASCIIとJIS X 0201半角カナを使えるようにしたものです。
 文字コードの切り替えには、ASCIIからJIS X 0201には「.(I」(0x1B 28 29)、JIS X 0201からASCIIには「.(B」(0x1B 28 42)という、Escで始まる3文字のコードを使っています。これをエスケープシーケンスというものです。
 アイウエオは12345に化けていますので、7ビット系です。
 エスケープシーケンスについては、ISO-2022-JPを説明するときにまた説明することもあるでしょう。ちなみにISO-2022-JPでは半角カナの使用を認めていません。