MIRACLE
メールサービス申込 ユーザー登録 パートナー情報
お問い合わせ FAQ サイトマップ
MIRACLE LINUXの特長 製品紹介 サービス案内 購入 サポート 技術フォーラム

プロフィール

コアテクノロジー部

ミラクル・リナックスのOS開発やサポートを担う、技術部の精鋭陣が交代で担当します。

ミラクル関連リンク

採用情報

サイト検索

2008年5月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

« 不定期Wine談義(2) : AsianuxでWineをセットアップする | メイン | ポストモーテム »

EUC-JP と Shift_JIS

弊社ブログユメのチカラ で、MySQL で ujis の 0x5C が sjis の 0x815F に変換されてしまう問題 が取り上げられていましたので、なぜ、そのような変換が行なわれるのか、そしてそのような実装が間違いとは言いきれない事を話たいと思います。

MySQL での ujis と sjis は、それぞれ、IANA で定義されている EUC-JP と Shift_JIS に相当します。

まずは、それぞれの定義を見てみましょう。

EUC-JP の定義

Name: Extended_UNIX_Code_Packed_Format_for_Japanese
MIBenum: 18
Source: Standardized by OSF, UNIX International, and UNIX Systems
        Laboratories Pacific.  Uses ISO 2022 rules to select
               code set 0: US-ASCII (a single 7-bit byte set)
               code set 1: JIS X0208-1990 (a double 8-bit byte set)
                           restricted to A0-FF in both bytes
               code set 2: Half Width Katakana (a single 7-bit byte set)
                           requiring SS2 as the character prefix
               code set 3: JIS X0212-1990 (a double 7-bit byte set)
                           restricted to A0-FF in both bytes
                           requiring SS3 as the character prefix
Alias: csEUCPkdFmtJapanese
Alias: EUC-JP  (preferred MIME name)

Shift_JIS の定義

Name: Shift_JIS  (preferred MIME name)
MIBenum: 17
Source: This charset is an extension of csHalfWidthKatakana by
        adding graphic characters in JIS X 0208.  The CCS's are
        JIS X0201:1997 and JIS X0208:1997.  The
        complete definition is shown in Appendix 1 of JIS
        X0208:1997.
        This charset can be used for the top-level media type "text".
Alias: MS_Kanji
Alias: csShiftJIS

ここで注目すべき点としては、0x00~0x7F の部分で、EUC-JP は US-ASCII、Shift_JIS は JIS X 0201 ラテン文字 (ローマ文字) となる点です。

MySQL での文字コード変換は、Unicode 経由での変換となっていますので、IANA の定義にしたがって、EUC-JP と Unicode、Shift_JIS と Unicode の対応関係を表にすると次の様になります。(問題になるコードポイントのみピックアップ)

EUC-JP と Unicode の対応表
EUC-JPUnicode
0x5C REVERSE SOLIDUS U+005C REVERSE SOLIDUS
0x7E TILDE U+007E TILDE
0xA1C0 REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS
0xA1EF YEN SIGN U+00A5 YEN SIGN
0xA1B1 OVERLINE U+203E OVERLINE
Shift_JIS と Unicode の対応表
Shift_JISUnicode
0x5C YEN SIGN U+00A5 YEN SIGN
0x7E OVERLINE U+203E OVERLINE
0x815F REVERSE SOLIDUS U+005C REVERSE SOLIDUS
0x818F YEN SIGN U+FFE5 FULLWIDTH YEN SIGN
0x8150 OVERLINE U+FFE3 FULLWIDTH MACRON (JIS規格参照)

この対応表を使って、EUC-JP の 0x5C を Shift_JIS に変換すると、どうなるか見てみましょう。

EUC-JP (ujis)UnicodeShift_JIS (sjis)
0x5C U+005C 0x815F

EUC-JP の REVERSE SOLIDUS (0x5C) が Shift_JIS の REVERSE SOLIDUS (0x815F) に変換されています。これは、MySQL で ujis の 0x5C が sjis の 0x815F に変換される動作と同じですね。

MySQL の変換は、利用者からしてみれば不具合でしかないわけですが、上記のように IANA の定義に従ってまじめに実装を行なった結果だと分かるかと思います。

ただし、MySQL では Shift_JIS (sjis) の 0x5C YEN SIGN を EUC-JP (ujis) の 0xA1EF YEN SIGN に変換せずに、0x5C REVERSE SOLIDUS に変換しているので、規格に厳密に実装しているわけでも無さそうです。

なぜ、そのような実装になるのか思い当たるフシはありますが、ここでは省略させてもらいます。

mysql> SELECT HEX(CONVERT( _sjis 0x5C using ucs2 ));
+---------------------------------------+
| HEX(CONVERT( _sjis 0x5C using ucs2 )) |
+---------------------------------------+
| 005C                                  |
+---------------------------------------+
1 row in set (0.00 sec)

EUC-JP、Shift_JIS の実装に関しては、伊藤隆幸さんのホームページの 従来の文字コードとUnicodeの対応に関する諸問題 > 6. ASCIIとJIS X 0201ローマ文字 で説明されているように、JIS X 0208や JIS X 0212 はなるべく FULLWIDTH に追いやってしまうという事にすれば、今回のような文字化けを回避可能となります。

cp932 と eucjpms (eucJP-ms) に関しては、JIS X 0208 や JIS X 0212 を FULLWIDTH に追いやってしまう事に加えて、JIS X 0201 ラテン文字を Unicode の U+0000~U+007F のコードポイントに対応付けするという事をして、Unicode 以前の US-ASCII と JIS X 0201 ラテン文字の扱いと同じ解釈で処理が行なえるようになっています。

規格遵守をしようと思って実装を行なうと、実際には利用者にとっては使えないものを作ってしまうという不幸をなくす為にも、規格遵守した時に矛盾が生じないように規格の改正などが必要かもしれません。

トラックバック

このページのトラックバックURL:
http://www.typepad.jp/t/trackback/4447/6583690

このページへのトラックバック一覧 EUC-JP と Shift_JIS:

コメント

まず、JIS X 201を改正すべきなんじゃよー。
1.規格をASCII部分と半角カタカナ部分の2つに分岐させる
2.ASCII部分はASCIIと完全に同じ規定にする。Yenとかoverlineとかステステ。ただし、過去の互換性からフォント表示をYenとかoverlineとかでしても規格不一致とはみなさない。という一文だけ追加する

現実的にはすべての文字コードは7bit部分にASCIIを期待していて、世の中のソフトもみんなそう実装されているのに、いや、実は規格上の定義はそうではなくて・・・とかヘンな話しをするから、混乱するのじゃよー。

と、極論を吐いてみるテスト

現実主義者としては、仮に規格を改正しても、現在の実装は残るし現場で困っている人を救えない、なんてことを思っていて、じゃあ、なんで規格を改正するんだよと問われれば、それは規格原理主義者の口を(あぐ、うわ、ぐはああああ…)

極論返し。

しかし、50円なりを¥50と表示するの\50では全然違うしなあ。

規格違反を指摘するのが簡単であっても、規格違反にならず実用的に使えるような実装を行なう事は、現状では、困難であるという事を認識していただければと思っています。

ISO/IEC 10646(≒Unicode) は、ISO/IEC 646 の各国版との互換性を考え、U+0000 から U+007F は ISO/IEC 646 IRV(US-ASCII) 決め打ちにしなければいいだけの話なのかもしれません。

コメントを投稿

会社情報 採用情報 個人情報保護方針 商標等取り扱い事項 English
Copyright(c)2000-2006 MIRACLE LINUX CORPORATION. All Rights Reserved.