シフトJIS では、第3水準・第4水準の漢字を扱えないのか? (4)-シフトJIS の成り立ち-

シフトJIS の成り立ちには、歴史的な経緯がある。この辺の話は、『インターネット時代の文字コード』(共立出版、2002年;現在は絶版)に詳しく書かれている。本稿も、かなりの部分、この本を参考にさせていただいた。
1969年に JIS X 0201 が制定された。これは、ISO 646 の拡張と見て良い。7ビット版と8ビット版の両方があるらしいのだが、ここでは、8ビット版について説明する。
8ビットということは、2の8乗=256通りの表現力があることになる。先ずこれを16進数で表す方法について復習したい。図では、行(横方向)、列(縦方向)ともに0からFまでの16個、つまり16の2乗=256個のマスで表される。2進数の8桁は、16進数の2桁で表せる。例えば、文字「A」の場所は 41(16進数)であり、10進数で言えば、4×16+1×1 = 65である。文字「ア」の場所は B1(16進数)、10進数で11×16+1×1 = 177である。16進数の FF は16×15+1×15 = 255(10進数)であり、0から255までの256通りが表せるということである。
JIS X 0201 では、ISO 646 部分である英数字とカタカナが規定されている。

JIS X 0201
  0 1 2 3 4 5 6 7 8 9 A B C D E F
0       0 @ P ` p          
1     ! 1 A Q a q        
2     " 2 B R b r        
3     # 3 C S c s        
4     $ 4 D T d t        
5     % 5 E U e u        
6     & 6 F V f v        
7     ' 7 G W g w        
8     ( 8 H X h x        
9     ) 9 I Y i y        
A     * : J Z j z        
B     + ; K [ k {        
C     , < L ¥ l |        
D     - = M ] m }        
E     . > N ^ n        
F     / ? O _ o       ソ    

次いで、1978年に JIS X 0208 が制定された。これには、漢字、ひらがな、カタカナ、英数字、記号が含まれる。全ての文字の符号を区点で表し、94区×94点=8836文字分のスペースがある。
JIS X 0201 にも JIS X 0208 にも、カタカナと英数字が存在するが、JIS X 0208JIS X 0201 の上位互換にはならなかった。これには、色々な理由があったらしいのだが、JIS X 0201 では、濁点・半濁点はそれぞれコードポイントが与えられているのに対して、JIS X 0208 には濁点・半濁点付きのカタカナが収録されているという違いがある。
いずれにしても、JIS X 0208JIS X 0201 を飲み込めなかったことにより、この2つを同時に使える文字コードの需要が生まれ、シフトJISが成立することになったのである。そして、カタカナと英数字について JIS X 0201 由来のものと JIS X 0208 由来のものが、シフトJISに混在することになったが、JIS X 0201 由来のものを半角カタカナ・半角英数字、JIS X 0208 由来のものを全角カタカナ・全角英数字とすることで、棲み分けがなされている。
では具体的に、シフトJIS がどのようにして JIS X 0201JIS X 0208 を同時に扱っているのか見てみたい。シフトJIS は、元々ベンダー主導で策定された符号化方式であるが、後追いする形で JIS X 0208 の附属書に規定されているので、それに沿って解説して行こうと思う。
先ず、シフトJIS の基本的なアイデアは、JIS X 0201 については、そのまま1バイトで表し、JIS X 0208 については、2バイトで表す。「ア」は、シフトJIS でも B1 である。
2バイト文字の1バイト目は、JIS X 0201 と制御文字が定義されていない領域に埋め込む。それは、1バイト目で、1バイト文字なのか2バイト文字なのか判別するためである。

  1バイト符号(JIS X 0201 と制御文字)
  2バイト符号の第1バイト(JIS X 0208 の1区から62区)
  2バイト符号の第1バイト(JIS X 0208 の63区から94区)

シフトJIS の1バイト符号および2バイト符号の第1バイト
  0 1 2 3 4 5 6 7 8 9 A B C D E F
0                                
1                                
2                                
3                                
4                                
5                                
6                                
7                                
8                                
9                                
A                                
B                                
C                                
D                                
E                                
F                                

図で見ると、81 から9F、E0 から EF、計47個の符号が、2バイト文字の1バイト目のために使える。しかし、これをそのまま JIS X 0208 の94個の「区」に当てはめようとすると足りないことがわかる。1バイト目を「区」に使い、2バイト目を「点」に使うことには変わりはないのだが、ここでちょっとしたアイデアが発揮される。異なる区のために同じ1バイト目の符号を使っても、2バイト目が違えば問題ないのである。2バイト目は、JIS X 0201 のために使われていない領域という制限はないので、充分な領域が確保される。実際、2バイト目のためには、40 から 7E、80 から FC という計188=94×2 個の符号が用意されている。47×188=8836=94×94 でJIS X 0208 の全ての文字が扱えることがわかる。
さて、94個の区を47個の1バイト目の領域に埋め込むために、(区番号-1)を2で割り、小数点以下を切り捨てる。
そして、区番号が1以上、62以下の時、これに16進数の 81 つまり10進数の129を足したものが1バイト目の符号である。81 から9F の領域に1区から62区を割り当てる方法である。確認してみると、1区、2区は 0+81(16進数)で 81、61区、62区は 30+129=159(10進数)を16進数に変換して 9F である。
区番号が63以上、94以下の時は、(区番号-1)を2で割って小数点以下を切り捨てたものに16進数の C1(10進数の193)を足す。これは、E0 から EF に63区から94区を割り当てるためだ。63区、64区は 31+193=224 を16進数に直して E0、93区、94区は 46+193=239(16進数で EF)である。
2バイト文字の1バイト目は、1つの符号につき2つの「区」がマッピングされているが、区番号が偶数であるか奇数であるかによって「点」を2バイト目に割り振る領域を分けているので、符号が重複することは無い。

  2バイト符号の第2バイト(JIS X 0208 の奇数区で1点から63点)
  2バイト符号の第2バイト(JIS X 0208 の奇数区で64点から94点)
  2バイト符号の第2バイト(JIS X 0208 の偶数区で1点から94点)

シフトJIS の2バイト符号の第2バイト
  0 1 2 3 4 5 6 7 8 9 A B C D E F
0                                
1                                
2                                
3                                
4                                
5                                
6                                
7                                
8                                
9                                
A                                
B                                
C                                
D                                
E                                
F                                

具体的には、区番号が奇数の場合、点番号が1以上63以下の時は、点番号に16進数の 3F(10進数の63)を足す。点番号が64以上94以下の時、点番号に16進数の 40(10進数の64)を足す。これは、区番号が奇数の場合、2バイト目の 40 から 7Eに1点から63点、80 から 9E に64点から94点を割り振るためである。
区番号が偶数の場合、点番号に16進数の 9E(10進数の158)を足す。これで、区番号が偶数の場合の1点から94点は、2バイト目の 9F から FC に割り当てられる。
例えば、17区63点の「円」は、シフトJIS897E であり、18区63点の「貨」は、シフトJIS89DD である。
以上が、シフトJIS の説明であるが、表題の「シフトJIS では、第3水準・第4水準の漢字を扱えないのか?」に戻ると、「シフトJIS文字集合として JIS X 0201JIS X 0208 を使っているので、第2水準漢字までしか扱えない」というのが、シフトJIS に対する最初の理解で間違っていない。しかし、この段階では、『増補改訂 JIS 漢字字典』に載っていた第3水準漢字「嚬」の S-JIS: 885C というコードの謎は残ったままである。