Open Source WEB

前回の復習をしておこう。以下のように、〜 が ~ に化けたのであった。

mysql> SET NAMES ujis;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT '〜';
+-----+
| ~   |
+-----+
| 〜 |
+-----+
1 row in set (0.00 sec)

原因を調べるには、16進数にしてみるに限る。

mysql> select hex('〜');
+----------+
| hex('~') |
+----------+
| 8FA2B7   |
+----------+
1 row in set (0.00 sec)

SET NAMES ujis としたので、これは ujis の文字を16進数表示したものである。 しかし、1文字しかないはずなのに3バイトになってしまった。

最初が 8F になっているので、これは JIS X 0212(補助漢字)ってことだ。 というわけで仕方なく補助漢字のテーブルを眺めたら、 02区23点に~が入っていた。これにされちゃったみたいである。

〜は、補助漢字ではなくて、JIS X 0208 の01区33点の方でなくてはならないのに、 勝手な解釈が行なわれてしまったようだ。この文字は、EUC-JPでは 16進数ではA1C1になる。

ということで、16進数で文字を指定してみよう。

mysql> SELECT _ujis 0x7E, _ujis 0x8FA2B7, _ujis 0xA1C1;
+---+-----+----+
| ~ | ~   | 〜 |
+---+-----+----+
| ~ | 〜 | 〜 |
+---+-----+----+
1 row in set (0.00 sec)

0x8FA2B7の方は怪しい動きをしてくれる。 0xA1C1の方は、どちらも〜になっているので問題なし。 sjisに変換するとどうなるか調べてみよう。

mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING sjis));
+-----------------------------------------+
| HEX(CONVERT(_ujis 0x8FA2B7 USING sjis)) |
+-----------------------------------------+
| 7E                                      |
+-----------------------------------------+
1 row in set (0.00 sec)

なんと、単なる1バイトの 7E になってしまった。 utf8にするとどうなるか。

mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING utf8));
+-----------------------------------------+
| HEX(CONVERT(_ujis 0x8FA2B7 USING utf8)) |
+-----------------------------------------+
| 7E                                      |
+-----------------------------------------+
1 row in set (0.00 sec)

やはり、7Eになってしまった。ついでに latin1 を試してみよう。

mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING latin1));
+-------------------------------------------+
| HEX(CONVERT(_ujis 0x8FA2B7 USING latin1)) |
+-------------------------------------------+
| 7E                                        |
+-------------------------------------------+
1 row in set (0.00 sec)

これはすごいや。何で latin1 に変換できちゃうんだろう。

mysql> select HEX(CONVERT('〜' USING sjis));
+------------------------------+
| HEX(CONVERT('~' USING sjis)) |
+------------------------------+
| 7E                           |
+------------------------------+
1 row in set (0.00 sec)

'〜' は ujisとして MySQLサーバに渡され、そこで sjisに変換されると 1バイトの7Eになってしまった。

sjisは補助漢字はサポートできないので、 補助漢字として解釈された〜が、~(7E)にされてしまうのは仕方がない。 しかし、本来なら、ujisだろうがsjisだろうが JIS X 0208 にある、 普通に「から」の意味でよく使用される〜として解釈してくれないことには トラブルに陥る。

ということは、

mysql> select '〜' = '~';
+-----------+
| '~' = '~' |
+-----------+
|         0 |
+-----------+
1 row in set (0.00 sec)

といういことで、 2つの文字列 '〜' と '~' は異なるという当然の結果になるのだが、 '〜' を sjis に変換してから比較すると

mysql> select CONVERT('〜' USING sjis) = CONVERT('~' USING sjis);
+---------------------------------------------------+
| CONVERT('~' USING sjis) = CONVERT('~' USING sjis) |
+---------------------------------------------------+
|                                                 1 |
+---------------------------------------------------+
1 row in set (0.00 sec)

となり一致する。

つまり、ujis の '〜' と '~' が sjis に変換すると、どちらも同じ '~'(7E)に変換されてしまう。 要するに、ujis と sjis の文字が1対1対応していないのだ。

それにしても、何で〜を補助漢字にしてしまうんだ。 いったいどこからそんな馬鹿なことを考えついたんだろう。

〜 は補助漢字 …… そんな馬鹿な


\(5C)も1対1対応していない

\(5C)の場合についても同じテストをしておこう。

mysql> select CONVERT('\' USING sjis) = CONVERT('\\' USING sjis);
+----------------------------------------------------+
| CONVERT('\' USING sjis) = CONVERT('\\' USING sjis) |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
1 row in set (0.00 sec)

まったく同じ結果になってしまった。やれやれ。

まいったなぁ、どうすればいいんだ。


戻る:全角の〜が半角の~に文字化けする

次へ:新キャラクタセットcp932,eucjpmsとは何か


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us