シフトJIS では、第3水準・第4水準の漢字を扱えないのか? 番外編(1)-JIS X 0213 が第1面に追加した非漢字を何と呼ぶか?-

2000年版の JIS X 0213 は、JIS X 0208 で規定されていた6879文字に4344文字加えて、計11223文字を規定している。JIS X 0208 に比べて増えた文字は、第1面に1908文字、第2面に2436文字である。
第2面の2436文字は全て第4水準漢字である。第1面に追加した1908文字については、漢字以外も含まれる。具体的には、丸付き数字などである。これらの文字は、第何水準と呼んだら良いのだろうか?
JIS X 0213 の規格書を読んでみると、この規格の定義する「漢字集合」は、「この規格で規定する図形文字集合の全体」(4. c))であり、「漢字集合中の図形文字の種類」は「特殊文字、数字、数字に準じるもの、ラテン文字、拡張ラテン文字、平仮名、片仮名、ギリシア文字、キリール文字、漢字、囲み文字、けい線素片及び互換用文字とする。」(6.5.2)と書いてある。
その上で、6.5.2項の j)「漢字」のところを読んでみると、「JIS X 0208 の第1水準漢字集合2965文字及び第2水準漢字集合3390文字の計6355文字並びに第3水準漢字集合1249文字及び第4水準漢字集合2436文字」とあるので、第n水準漢字集合と言った場合、「漢字集合」の中でも特に漢字(つまり、特殊文字、数字、数字に準じるもの、ラテン文字、拡張ラテン文字、平仮名、片仮名、ギリシア文字、キリール文字、囲み文字、けい線素片及び互換用文字は含まない)を指していることがわかった。
よって、JIS X 0213 が第1面に追加した1908文字の内、1249文字は第3水準漢字だが、残りの659文字に関しては第3水準漢字と呼ばない。
ここで改めて、この規格の冒頭「1. 適用範囲」を読むと、「この規格は、第4水準漢字集合を除く8787文字からなる符号化漢字集合と第4水準漢字集合の2436文字からなる符号化漢字集合との二つの符号化漢字集合を規定する」とある。第1水準漢字集合2965文字と第2水準漢字集合3390文字、第3水準漢字集合1249文字を合計すると7604文字なので、「第4水準漢字集合を除く8787文字からなる符号化漢字集合」と言う場合の漢字集合は、狭義の漢字集合ではなくて、JIS X 0208 の6879文字とJIS X 0213 が第1面に追加した1908文字、つまり狭義の漢字以外も含めた第1面に存在する全ての文字を指している。
更に、3.2.1項には、「この規格の実装水準3に対して適合性を主張する場合、この規格で規定する文字のうち第4水準漢字集合を除く8787文字のすべてを実装し」と書いてあるので、JIS X 0213 が第1面に追加した1908文字の中の1249文字の第3水準漢字以外の659文字も「実装水準3」に含まれることになる。よって、JIS X 0213 が第1面に追加した非漢字を「第3水準」と呼んで良さそうである。

シャオシャオとレイレイの見分け方

2021年に上野で生まれた双子のパンダ、シャオシャオとレイレイ。二頭を見分けるためにシャオシャオの背中には緑色の印が付けられているが、成長するに従い、二頭の個性が現れて来たようである。
先ずは目元から。象のようなしわしわの瞼をしているのがレイレイ、どんぐり眼なのがシャオシャオ。
そして、頭の形。正面から見た時に耳と耳の間の頭頂部のカーブが緩い(直線に近い)のがレイレイで、よりカーブしている(頭のてっぺんが尖り気味)のがシャオシャオである。

食塩水問題再び

以前も食塩水問題について書いた。
そこでの主張は、「x %の食塩水」とは何を意味するのか、問題文に明記すればよいというものだった。
しかし、まだ言い足りないことがあるので、再びこの主題で書いてみることにした。
例題を再掲する。

例題(1) 5%の食塩水600g に10%の食塩水を混ぜて、7%の食塩水を作りたい。10%の食塩水を何g 混ぜればよいか。

先ずは、小手調べから。
「水500ml に16%の醤油と14%のみりんを加える」と言ったら、80ml の醤油と70ml のみりんを加えると解釈するのが自然ではないだろうか? これを塩分濃度16%の醤油とかアルコール度数14のみりんとか言い出したら、余程ひねくれた解釈だと思うのだが。では、なぜ食塩水の場合は、「x %の食塩水」で塩分濃度 x %の食塩水なのだ? 塩分濃度のことを言いたいのなら、せめて「塩分濃度 x %の食塩水」と言えばいいじゃないか。ええじゃないか。
教育関係者の間では、「食塩水問題が苦手な子供には、食塩水の濃度が食塩水全体に対する食塩の割合だという基本的なことがわかっていない子が多い」という論調が度々現れる。
以前の投稿で、私は消費税の例を出したが、建築の世界では、含水率というものがある。含水率は、建築材料に含まれる水分の割合を表すものだが、これには乾量基準を使う。乾量基準含水率は((乾燥前の材料の質量-乾燥後の材料の質量)/乾燥後の材料の質量)で求める。(上記は質量基準質量含水率の場合で、他にも容積基準質量含水率や容積基準容積含水率がある。)別の分野では、湿量基準で含水率を計算することがあり、その場合は、(水分/乾燥前の試料)で計算し、これにも質量で計算する場合や体積で計算する場合がある。どれが正しくてどれが間違っているというのではなく、それぞれにそのように定義され、それぞれに用途がある。食塩水問題における食塩水の濃度も(食塩/(水+食塩))と定義しただけであり、「食塩水問題が苦手な子供」は「基本的なことがわかっていない」のではなくて、その定義を知らなかっただけなのだから、教えてあげればいいのである。というか、問題文に但し書きとして入れればいいというのが私の提言である。
食塩水の濃度を質量で計算することに関しては、問題の作りやすさの都合でそうしているだけだ。だから、食塩水の濃度を質量で計算してほしいのなら、そう言えば済む話だ。
さて、以上のように、「x %の食塩水」とは、塩分濃度が x %の食塩水溶液で、塩分濃度は食塩水溶液における食塩の割合を質量で計算したものだということを問題文に明記すればよいというのが私の主張だが、相変わらず例題(1)のような問題が中学入試などで出題されるとしたら、教える側としてはどうしたらいいだろうか?

先生:「5%の食塩水600g を作るためには、水を何g 使えばいいかな?」
生徒たち:「…」
先生:「そうだね。600g の食塩水の中には600×(5/100)g =30gの食塩があるから、600-30=570g だね。」

ではなくて、受験は一種の競技であり、その競技のルールを知らないと勝負にならないこと、「x %の食塩水は、塩分濃度が x %の食塩水溶液のことで、塩分濃度は食塩水溶液における食塩の割合を質量で計算する」というのは食塩水問題という競技のルールであり、そのようなルールは往々にして成文化されていない、つまり暗黙のルールであるという、ぶっちゃけ話をしてほしいのだ。こういう学校では教えてくれないことを教えてくれるのが、塾の存在意義だと私は思っている。
では、塾に行けないような家庭の子供はどうしたらいいのか?
ごもっともである。
ごもっともであるが、そのような家庭の子供はうちの学校には来てほしくないというのが、学校側と保護者側の一致した本音ではないのかね? そして勿論、受験産業はそこに商機を見出している。この本音が変わらない限り、食塩水問題のような問題は、手を変え品を変え出題されると私は見ている。
食塩水問題は、ある宗派ではお焼香を何回するとか、ある流派では薄茶を泡立てるとか泡立てないとか、そのコミュニティーに属する者ならば当然知っておくべき常識を問う問題なのだ。小学校受験いわゆるお受験では、もっと露骨にマナー問題が出題される。これは、自分たちのコミュニティーの作法を知らない人間をふるい落とすための試験である。
これに関しては、私はプラクティカルに考えればいいと思っている。そのコミュニティーの仲間入りをしたいのであれば、お金を払って塾に行けばいい(「5%の食塩水ってどういう意味かな。考えてみよう。」とか言ってる塾には行かないように)。塾に行くお金が無いなら無いなりに、あの手この手で彼らの行動原理を研究し、しきたりを模倣して、そのコミュニティーの一員になりきればいい。
もっとも、そのコミュニティーに所属する価値があるのかないのかは、また別問題である。身内と部外者を峻別する儀式に明け暮れる閉鎖的な集団が、いずれオワコン化することは、じゅうぶんに考えられる。盛者必衰、諸行無常であることを思えば、ある時代のある地域のあるコミュニティーが永続することはあり得ない。
絶対王政の最期の甘い汁を吸うのか、新しい潮流に身を投じるのかは、各自で判断すればよい。
そして、自由・平等・友愛を掲げて絶対王政を倒したはずのブルジョワジーが資本家として新たな支配階級となったように、食塩水問題くだらなーいとか言っていた我々も、すっかり自分の地位を確立した頃には、新参者を拒む閉鎖的なコミュニティーを形成しないとは限らない。

シフトJIS では、第3水準・第4水準の漢字を扱えないのか? (5)-JIS X 0213 を使うシフトJIS もある-

前回シフトJIS文字集合として JIS X 0201JIS X 0208 を使っていると書いたが、JIS X 0208 の代わりに JIS X 0213 を使うシフトJIS が存在する。
その名も、Shift_JISX0213 で、JIS X 0213 の附属書に規定されている。
先ず、JIS X 0213 について説明すると、この規格は2000年に制定された。これは、JIS X 0208 で規定された文字を全てそのまま含み、それに加えて第3水準・第4水準と呼ばれる文字を規定している。
JIS X 0208 が、94区×94点の8836個のスペースを用意しているのに対し、JIS X 0213 はもう1つ94区×94点のスペースを用意し、これを第2面と呼んでいる。それに伴い、JIS X 0208 で用意されていた94区×94点を第1面と呼んでいる。
第1面の JIS X 0208 と共通の文字は、区点位置も JIS X 0208 と同じだが、実は、 JIS X 0208 は94区×94点の8836個のスペースを全て使っている訳ではない。JIS X 0208 が規定しているのは、6879字であり、第1面には空きがある。JIS X 0213 は、この空きに新たに文字を詰め込んでいる。これが、第3水準の文字である。それでも、隙間なく詰め込んだ訳ではなく、第1面に規定されるのは8787字である。そして、第2面には、2436字が規定され、これが第4水準の文字である。
では、Shift_JISX0213 が実際どのように JIS X 0201JIS X 0213 を符号化しているのか見てみよう。
JIS X 0201 については、そのまま1バイトで表す。
JIS X 0213 の第1面については、(区番号-1)を2で割って小数点以下を切り捨て、区番号が1以上、62以下の時は、これに16進数の 81 を足したもの、区番号が63以上、94以下の時は、16進数の C1 を足したものを1バイト目の符号とする。
そして2バイト目の符号は、区番号が奇数の場合、点番号が1以上63以下の時は、点番号に16進数の 3F を足し、点番号が64以上94以下の時、点番号に16進数の 40 を足したものであり、区番号が偶数の場合、点番号に16進数の 9E を足したものである。
ここまでは、JIS X 0208 を使ったシフトJIS と同じである。ただし、上で見たように、JIS X 0208 の第1面(というか第1面しか無いのだが)には、空きがあった。(JIS X 0213 の第1面にも空はある。)ということは、区番号1以上62以下とか63以上94以下とか言っても、該当しない箇所があった訳だ。
JIS X 0213 の第2面については、区番号が1の時、3以上5以下の時、8の時、12以上15以下の時、区番号に16進数の 1DF(10進数の479)を足したものを2で割って小数点以下を切り捨てたものから、区番号を8で割って小数点以下を切り捨てたものに3を掛けたものを引いたものが1バイト目の符号であり、区番号が78以上94以下の時、区番号に16進数の 19B(10進数の411)を足したものを2で割って小数点以下を切り捨てたものが、1バイト目の符号である。
これは、2面1区、3~5区、8区、12~15区、78~94区を1バイト目の F0 から FC に割り当てるためである。因みに、JIS X 0213 の第2面には、これらの区以外には文字は存在しない。
そして、2バイト目の符号は、第1面の時と同じ方式で計算する。
具体例で見てみると、1面15区29点の第3水準漢字「嚬」は、885C と計算される。これが、『増補改訂 JIS 漢字字典』に載っていた S-JIS の正体である。
もう一つ具体例を見てみると、2面1区21点の第4水準漢字「亻」(にんべん)は、F054 になる。
以上が、Shift_JISX0213 の説明である。
シフトJIS では、第3水準・第4水準の漢字を扱えないのか?」に対しては、「Shift_JISX0213 を使えば、第3水準・第4水準の漢字も扱える」が答えだ。ただし、規格上は第3水準までの実装というものが許されているらしく、その場合は、第3水準までである。
ここで、「Shift_JISX0213 というものがあるのはわかった。でも、そんなものにお目にかかったことが無い。」という方もいるかもしれない。たしかに、Shift_JISX0213 は、それほど普及しているとは言えないが、実装されていないということは無い。
例えば、macOS ではよく使われているテキストエディタの CotEditor では、エンコーディングとして「Shift JIS X0213」を選べる。さらに言えば、macOS に標準で付属しているテキストエディットでも同様である。しかし、こちらは[環境設定]->[開く/保存]->[エンコーディング]の「エンコーディングリストをカスタマイズ」をしないとメニューに現れて来ないので、あまり知られていないのかもしれない。
早速、CotEditor またはテキストエディットで「Shift JIS X0213」を選んで、「嚬」(第3水準)や「亻」(第4水準)を貼り付けてみると、きちんと表示されるし保存も出来る。このファイルを秀丸エディタのバイナリモードで開くと、「嚬」は 88,5C,「亻」は F0,54,であることが確認できた。

シフト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 というコードの謎は残ったままである。

秀丸エディタの「ファイルを読み込みし直す」と「内容を維持したまま適用」

秀丸エディタエンコードの種類を切り替える時、メッセージボックスが出て来て、「ファイルを読み込みし直す」か「内容を維持したまま適用」するか、キャンセルするかの選択を求められる。
「ファイルを読み込みし直す」を選択すると、選択されたエンコードの種類で、ファイルを読み込みし直す。編集した内容を保存する前に(タイトルバーのファイル名の横に“(更新)”が出ている状態)読み込みし直そうとすると、再読み込みをしても良いかというメッセージボックスが現れ、“はい”を選択すると、編集していた内容は破棄され、最後に保存したファイルの内容が当該エンコードの種類で読み込まれる。
編集している内容とファイルが一致する場合(最新の状態をファイルに保存した時)は、その最新の状態のものを当該エンコードの種類で読み込みし直す。
「ファイルを読み込みし直す」は、ファイルの内容には変更を加えない。間違ったエンコードの種類を指定してしまったと思った時は、元のエンコードの種類で読み込みし直せば、無事に戻れる。
「内容を維持したまま適用」を選択すると、表示される文字はそのままで、バイナリとしての情報が変化する。例えば、「あ」は UTF-8 では E3 81 82 だったのが、日本語(Shift-JIS)に「内容を維持したまま適用」で変更すると、82 A0 になる。そして、タイトルバーのファイル名の横に“(更新)”が出る。この状態では、まだファイルに保存されていないので、間違えたと思ったら、保存しなければ良いだけである。
勿論、その前の段階でエンコードの種類の切り替え自体を中断したい場合は、キャンセルを選ぶ。

シフトJIS では、第3水準・第4水準の漢字を扱えないのか? (3)-文字集合と符号化-

文字コードを語る上で必須なのが、文字集合と符号化の理解である。
文字集合は、その名の通り、当該文字コードで規定されている文字の集合である。
符号化は、各々の文字に番号を割り当てることと言っても良いのだが、注意が必要だ。ASCII のような古典的な文字コードの場合、各々の文字に割り当てられたコードポイントが、そのままコンピュータ上の符号になっていることもあるが、シフトJISEUC-JP などの場合、ASCII や JIS X 0201 のコードポイント、JIS X 0208JIS X 0212 の区点、JIS X 0213 の面区点という、各々の文字に割り当てられた番号をコンピュータ上のバイト列に変換する符号化が存在する。
Unicode の場合、(JIS X 0208JIS X 0212JIS X 0213などを含む)各国の文字コードに存在する文字が集計された上で、各文字に一つの code point が割り当てられる。例えば、U+56AC は、「嚬」に割り当てられた Unicode code point である。これを、code units として表現する方式が encoding forms であり、UTF-8UTF-16UTF-32 が存在する。さらに、これらが実際どのバイトオーダーでコンピュータに格納されるのかが、encoding schemes であり、UTF-8UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-32LE が存在する。UTF-8 の場合、ビッグエンディアンとリトルエンディアンは存在しない。E5 9A AC というバイト列は、「嚬」という文字を UTF-8 で実際に符号化した結果である。