前の章「
テキストの色替え」ではPOST と GETを説明しながら、文字コードの変換を少し説明しましたが、この章では文字コードと文字化けについて説明をします。
CGIを使用するスクリプトで起こる文字化けの原因はPerlにあります。Pelrはそもそも日本語に対応できるように作られた訳ではありませんので、特定な条件のときに文字化けを起こします。下のスクリプトを実行してみてください。
l_moji_1.cgi
#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
require './heder_s.txt';
print "<h2>\n";
print "私の名前はココです。<br>\n";
print "イヌは<font color=\"red\">表で</font>駆け回るといいますが<br>\n";
print "私は疲れるので好きではありません。\n";
print "</h2>\n";
print "<hr>このスクリプトはSHIFT-JISで書かれています。\n";
require './fotter.txt';
exit;
|
-
私の名前はココです。
イヌは浮ナ駆け回るといいますが
私は疲れるので好きではありません |
上はSHIFT-JISで書かれています。(heder_s.txtとfotter.txt)
【→Perl Reference: require】
同じスクリプトをEUCで書いて見ます。(heder.txt)
#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
require './heder.txt';
print "<h2>\n";
print "私の名前はココです。<br>\n";
print "イヌは<font color=\"red\">表で</font>駆け回るといいますが<br>\n";
print "私は疲れるので好きではありません。\n";
print "</h2>\n";
print "<hr>このスクリプトはEUCで書かれています。\n";
require './fotter.txt';
exit;
|
l_moji_2.cgi
-
私の名前はココです。
イヌは表で駆け回るといいますが
私は疲れるので好きではありません |
同じ内容なのにSHIFT-JISでは文字化けが発生しています。これは何故でしょうか。
前の章で説明した文字コードについて、もう少し詳しく見ていきましょう。そのために前と同じ「入力フォーム」を使ってみましょう。ここをクリックして上の行に 表 、下の行に \ と入力して submit ボタンを押してください。
-
入力されたデータをそのまま侮ヲすると→kanji=%95%5C&suji=%5C
|
「表」は%95%5C、「\」は%5C になっていますね。文字種にはいろいろありますが、主に我々が使用しているのは「ASCII」と漢字で使う「SHIFT-JIS」です。その他漢字に使用するものに「JIS」や「EUC」コードもあります。
「ASCIIコード」
「ASCIIコード」(American Standard Cord for Information Interchange)はアメリカで決められた規格で、当然日本語は扱えません。
「ASCIIコード」
・a 〜 z と A 〜 Z のアルファベット
・0 〜 9 の数字
・!"#$%& などの記号などがあります
「ASCIIコード」には半角文字だけで全角文字はありません。SHIFT-JISなどで使っている A(全角)は「ASCIIコード」ではありません。
「ASCIIコード」は8ビット(1バイト)で表現され、0x00 〜 0x7F までが該当します。8ビットの先頭は必ずゼロです。
「JISコード」
「JISコード」は日本工業規格で決められた規格です。ASCIIコードに半角片仮名や漢字などを追加したものです。ASCIIコードと半角片仮名は1バイトで表現しますが、漢字は2バイトで現します。またASCIIコードと漢字コードの(2バイトの内の1バイト)値が重複してしまうため、ESC(エスケープシーケンス)を使ってASCIIコードと漢字コードの切り分けをしています。ESCには漢字コードの始まりを現す"1b 24 42"とASCIIコードの始まりを現す"1b 28 42"があります。
| ESC"1b2442" | 漢字 | ESC"1b2842" | ASCII | ESC"1b2442" | 漢字 |
|
「JISコード」
・ASCIIコードはそのまま使用(0x00〜0x71)
・半角カナは1バイト(0xa1〜0xdf)
・漢字は2バイト(0x8140〜0x9ffc, 0xe040〜0xfcfc)
「シフトJISコード」
「シフトJISコード」は「SJIS(エスジス)」との言います。日本のパソコンの殆どがこのシフトJISコードを使っています。MS-DOSの日本語化で生まれた文字コードです。シフトJISコードはJISコードと異なりコードの先頭にあたる1ビットが必ず1になっています。そのためASCIIコードと混在する時に、JISコードの様にESCシーケンスを使用する必要がなく、扱いやすい構成になっています。
「シフトJISコード」
・ASCIIコードはそのまま使用(0x00〜0x71)
・半角カナは1バイト(0xa1〜0xdf)
・漢字は2バイト(0x8140〜0x9ffc, 0xe040〜0xfcfc)
ただし、ASCIIコードと区別しやすいようにコードの先頭が1になっていますがが、2バイトで現す漢字の場合、2バイト目の先頭に0と1が混在しています。そのためPerlの特殊な記号 \ と誤認識されることが発生します。それが文字化けとなるわけです。例えば[表で]という文字はシフトJISコードでは 955c82c5 ですが、 5c が ASCIIコードでは \ ですので(Perlでは \ は強制的に文字とみなすという記号)、9582c5 つまり 9582 で[浮]、c5 で半角カナの[ナ]に化けてしまうわけです。[表]だけでなく2バイト目の先頭が 5c になる漢字は全て文字化けとなります。
- 申歳の予言・噂は欺瞞的構造だと十代ソン代表は暴露した
シフトJISで[表で]と現したいなら[表\で]と表の字の次に \マークを付け、次の1バイトが \マークだが文字とみなさないようにすれば文字化けは防げます。
#!/usr/local/bin/perl
print "Content-type: text/html\n\n";
require './heder_s.txt';
print "<h2>\n";
print "申歳の予言・噂は欺瞞的構造だと十代ソン代表は暴露した<p>\n";
print "申\歳の予\言・噂\は欺\瞞的構\造だと十\代ソ\ン代表\は暴\露した<p>\n";
print "</h2>\n";
print "<hr>このスクリプトはSHIFT-JISで書かれています。\n";
require './fotter.txt';
exit;
|
l_moji_3.cgi
いかがでしょうか。次の漢字の2バイト目の先頭が 5c にあたっています。
[申][予][噂][欺][構][十][ソ][表][暴]
いったい文字化けする漢字はいくつあるのでしょうか。それは40文字です。
「SHIFT-JISコードに 5C が含まれる漢字」にまとめてみました。
「EUCコード」
「EUCコード」(Extendes UNEIX Code)は日本語対応の UNIX で主に使われるコードです。EUCコードも漢字を現すのは2バイトですが、シフトJISコードと異なり2バイト目の先頭も1になっています。そのため文字化けが発生することはありません。またJISコードのようにESCシークエンスも必要ありません。Perlを書くにはこのEUCコードをお勧めします(Perlのスクリプトで読むデータも)。
「EUCコードド」
・ASCIIコードはそのまま使用(0x00〜0x71)
・半角カナは2バイト(0x8ea1〜0x8edf)
・漢字は2バイト(0xa1a1〜0xfefe)
・補助漢字は3バイト(0x8fa1a1〜0xffefe)
EUCで記述するためにEUCコードで使えるエディタが必要になります。私の場合は「秀丸」を使用しています。シェアウエアのソフトウエアで非常に使い勝手のいいものです。他にもEUCを扱えるソフトならどのようなものでも構いません。またシフトJISで書いて、サーバに送付するときEUCに変換して送ることのできるFTPソフトウエアもあります。
またPerl の日本語使用のために、jcode.pl という変換ライブラリがあります。これを使用すると CGI で受取るデータをシフトJISからEUCに変換することができます。
Copyright 2001-2002 Coco's Home. All rights reserved.