「潤オ」ってなにさ?

ネットで最近よく「潤オ」ってのを見かけるけど
何が文字化けてるんだろうと思ったら
「〜」らしい。

ここに詳しく書いてあった
http://echoo.yubitoma.or.jp/weblog/ClapHand/eid/449096/

——————————–

【文字化けはなぜおこるのか】

「潤オ」で検索すると結構ヒットします。

「潤オ」の検索結果

これは、「要潤オフィシャルサイト」は別として
「潤オ」が「潤オ」に文字化けして表示されているのですが、
理由がわからないという人が多いので少し説明します。

そもそもコンピュータに保存されている”文字”は、実は文字ではなく、
単なる 0 と 1 の集まりに過ぎません。( 0 か 1 しかないので2進数です。)

この2進数に文字を割り当てて表現する場合、
半角英数字と記号、半角カナも含めて256種類もあれば足りるので
一文字は、00000000 潤オ 11111111 の間のいずれかに割り当てて表現します。

例えば 10000001 という組み合わせは、半角英大文字の “A” にあたります。
これでは何が何だかわからなくなるので、プログラミングをするような場合は、
この2進数を 0 潤オ F の16進数に置き換えて表現します。

(2進) (16進) (10進) (文字)
10000001 : 41 : 65 : “A”
10000010 : 42 : 66 : “B”
10000011 : 43 : 67 : “C”

ちなみに16進数は、
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 … 1A 1B 1C 潤オ FD FE FF(255)
といった感じで数えます。

オンかオフが表現できる単位(つまり 0 か 1)を、1ビット、
半角一文字を表現できる単位(8ビット)を1バイトと呼びます。

コンピュータがまだ計算が主力で、
言語等の表現力は二の次だった時代はこれでも良かったのでしょうが、
256程度の文字数では日本語は表現できません。

仕方がないので、漢字は2バイト(16ビット)で表すことにしました。
0000000100000000 潤オ 1111111111111111
(0100 潤オ FFFF)

全角文字は、2バイトコード(または DBCS)と呼ばれます。
これに対し、半角文字(1バイトコード)は SBCS と呼んでいます。
・DBCS:ダブルバイトキャラクターセット
・SBCS:シングルバイトキャラクターセット

どこにどの文字を割り当てるかという決まりをコードセットと呼びますが、
ひとつのコードセットではひとつの言語(この場合は日本語)しか表現できません。
韓国語には韓国語の、中国語には中国語のコードセットが存在します。

また、日本語だけに絞ってみても複数のコードセットが存在します。
代表的な例として、
・Windows(DOS)でよく使われる シフトJIS
・UNIX系の OS でよく使われる EUC-JP
・汎用機(メインフレーム)でよく使われる EBCDIC
(ウルトラセブンの基地にあるようなタンス程の大きさのコンピュータのこと。
 でっかいオープンリールのテープが回ってて、穴がパンチされた紙テープが吐き出されてるやつ)
等が存在します。
 もとい(EBCDICは半角のコードでした)
 ・IBMはIBM漢字コード
 ・富士通はJEF
 ・NECはJIPS
 ・日立はKEIS
です。
 メーカーによって同じ2バイトの文字を表す場合でも、16進の文字コードがまったく異なります。
(汎用機の半角コードEBCDICに対して、UNIX系、DOS系のOSの半角コードはASCIIです)
 ASCIIは全世界共通です。

文字化けがおこる一つの原因は、どのコードセットで書かれた文書なのかが
OS(またはブラウザ等のアプリケーション)が判断できないことにあります。

もうひとつの代表的な原因として、半角カナの存在が挙げられます。
「インターネットの世界では半角カナは使うな」というお達しがあります。
文字化けの原因と成り得るからです。

実は、汎用機の EBCDIC を日本に移植する際、
全世界的に共通とすべき 0 潤オ 255 以内に属していた英小文字の部分を、
日本では半角カナ変えてしまったとういきさつがあります。

つまり、 「abc も ABC も同じだろ」と日本人(のIBM社員)は考え、
苦肉の策で「abc は (半角)アイウ 」として、英小文字を排除してしまいました。
このことが更なる混乱を招いております。(16進は、それぞれ 81 82 83)

たとえば、英語で書かれたプログラムで「Error!!」と表示されても、
日本語のOSでは「Eネネナネ!!」と表示されてしまい、なんのこっちゃわかりません。

つまりこの時点で同じ EBCDIC でも英小文字用と半角カナ表示用の
2つのエンコード(16進をフォントに翻訳;マッピングすること)を用意する必要がありました。
時代も最近になってくるとさすがにそれでは不便だろうということで、
カナの部分は変更せずに256以内の空いている箇所に英小文字を割り当てて両方表現できるEBCDICを作ってしまいました。
本来、abcであるべきコードはアイウのままで、abcは別の領域に割り当てたのです。
つまり似て非なるものが3種類存在します。めちゃくちゃです。本末転倒です。

また、日本語のような DBCS 圏の言語は、必ず全角と半角が混在します。
“1潤オ2″といった文字を表示したい場合、
どこからどこまでが半角なのかを判断する必要が生じます。
この判断の仕方もコードセットの違いにより異なっています。

・ASCII(半角)とシフトJIS(全角)の区別
 全角文字(2バイト)の1バイト目の値は、
 半角文字(1バイト)と重ならないようなコードが割り当てられています。

・ASCII(半角)とEUC(全角 一部半角)の区別
 シフトJISと同様に全角と半角は1バイト単位で分割しても重ならないようなコードが割り当てられています。
 ただし、普通JIS漢字と言えば、日本語でよく使うJIS第一水準、および、少しは使うであろう第二水準を指すことが多いのですが
(これら2つを合わせてJIS基本漢字と呼ぶこともあります)、
EUCはこれら2つに加えてほとんど利用価値のないJIS補助漢字と呼ばれる漢字もサポートしています。これらを加えてしまうと、
今度は2バイトでも足りなくなってきました。
そこで、JIS補助漢字の先頭1バイトに(この文字はJIS補助漢字ですよということを表す)漢字シフトコード付加することにしました。つまりJIS補助漢字に関しては3バイトコードです。
 また、半角カナ文字を区別するために半角カナ文字コードの先頭に対しても、
 それぞれシフトコードと呼ばれる「おかみさん。これは半角カナですよ」という1バイトの目印が付いています。
 つまり半角であるのにもかかわらず、実際には2バイトの領域を使用しています。
(これら漢字シフトコード・カナシフトコードにも16進の数値が割り当てられていますが、通常は画面上や印刷では表示されません)

・EBCDIC←→IBM漢字コード(および、他のメインフレーム向け漢字コード)
 残念ながら、2バイトコードを1バイト単位で分割すると半角文字とバッティングするコードが存在します。
 そこで、汎用機での全角と半角の区別は、EUCのような文字単位ではなく、連続する全角文字列の前後にシフトコードを付加し、
 シフトコードに挟まれている文字を全角と判断します。
 シフトコードのバイト数ですが、IBMと富士通は1バイト、NECや日立等は2バイトです。

そして冒頭の、「潤オ」が「潤オ」に文字化けする理由ですが、
これは EUC で保存された文書でのみ起こります。

EUC の「潤オ」は、見た目はひとつですが、(WindowsXPまでは異なります)
実は 16進で表すと A1C1 と 8FA2B7 の2種類の別の文字として存在します。
で、8FA2B7 の方が上で説明したJIS補助漢字です。
16進は2桁で1バイトですので、6桁あるから3バイトですね。先頭の”8F”がシフトコードです。

Windowsには A1C1 に相当する文字はありますが 8FA2B7 に相当する文字が存在しません。
そのため Windows では適当に変換され「潤オ」として表示されています(「オ」は半角です)。
UNIX系のOS(EUC-JP)では文字化けはしていないものと思われます。