EUC_JP_Solarisの動作検証

ご存知の通り,J2SEで実装されている文字コード"EUC_JP_Solaris"は"WINDOWS-31J"に対応する文字を含む"EUC_JP"系の文字コードです.またMySQLでは"eucjpms"という名前でver5.0.3から実装されています.通常のEUC_JPはujisですね.

このEUC_JP_SolarisというのはSunのドキュメントによればJ2SE1.5(5.0)から見受けられます.しかしJ2SE1.4でも動作が確認されているようです.

EUC_JP_Solarisの挙動を探るためのプログラムを書いてみました.ちょっと長いのでソースはこちらにアップしています.

http://ikda.net/resources/EUCJPSolarisTest.java

WINDOWS-31Jに含まれる文字集合「JISX0201」「JISX0208」「NEC拡張文字(row13)」「NEC選定IBM拡張文字」「IBM拡張文字」などに加え,ujisとeucjpmsでUnicodeへの変換ルールが異なる文字を使って順番に String.getBytes(encoding) でJava内のUnicodeからEUC_JP_Solarisのバイト列に変換し,再度 new String(byte[], encoding) でJavaUnicodeに復元します.

この際,EUC_JP_Solaris側に存在しない文字があると文字が破壊されて"?"になります.ブラウザで見た時に表示できず"?"になる文字もありますので,復元した文字が当初と同じであればtrue,破壊されていればfalseと出しています.さて結果のほうですが・・・

---------- test for WINDOWS-31J chars ----------
0xFF71, // 0xB100 of WINDOWS-31J, JISX0201.           : ア --> ア : true
0x65E5, // 0x93FA of WINDOWS-31J, JISX0208.           : 日 --> 日 : true
0x3231, // 0x878A of WINDOWS-31J, NEC special(row13). : ㈱ --> ㈱ : true
0x72B1, // 0xEDFC of WINDOWS-31J, NEC selected IBM.   : 菏 --> 菏 : true
0x6D6F, // 0xFAFC of WINDOWS-31J, IBM special.        : 芩 --> 芩 : true
0x8868, // 0x955C of WINDOWS-31J, one of '5c'.        : 表 --> 表 : true
---------- test for ujis chars ----------
0x005C, // 0x5C     YEN SIGN                          : \ --> \ : true
0x007E, // 0x7E     TILDE                             : ~ --> ~ : true
0xFFE3, // 0xA1B1   OVERLINE                          :  ̄ -->  ̄ : true
0x2015, // 0xA1BD   EM DASH                           : ― --> ? : false
0x005C, // 0xA1C0   REVERSE SOLIDUS                   : \ --> \ : true
0x301C, // 0xA1C1   WAVE DASH                         : ? --> ? : true
0x2016, // 0xA1C2   DOUBLE VERTICAL LINE              : ? --> ? : true
0x2212, // 0xA1DD   MINUS SIGN                        : ? --> ? : true
0x00A2, // 0xA1F1   CENT SIGN                         : ¢ --> ¢ : true
0x00A3, // 0xA1F2   POUND SIGN                        : £ --> £ : true
0xFFE5, // 0xA1EF   YEN SIGN                          : ¥ --> ¥ : true
0x00AC, // 0xA2CC   NOT SIGN                          : ¬ --> ¬ : true
0x007E, // 0x8FA2B7 TILDE                             : ~ --> ~ : true
0x00A6  // 0x8FA2C3 BROKEN BAR                        : ? --> ? : true
---------- test for eucjpms chars ----------
0x005C, // 0x5C     YEN SIGN                          : \ --> \ : true
0x007E, // 0x7E     TILDE                             : ~ --> ~ : true
0xFFE3, // 0xA1B1   OVERLINE                          :  ̄ -->  ̄ : true
0x2015, // 0xA1BD   EM DASH                           : ― --> ? : false
0xFF3C, // 0xA1C0   REVERSE SOLIDUS                   : \ --> \ : true
0xFF5E, // 0xA1C1   WAVE DASH                         : 〜 --> 〜 : true
0x2225, // 0xA1C2   DOUBLE VERTICAL LINE              : ‖ --> ? : false
0xFF0D, // 0xA1DD   MINUS SIGN                        : − --> ? : false
0xFFE0, // 0xA1F1   CENT SIGN                         : ¢ --> ? : false
0xFFE1, // 0xA1F2   POUND SIGN                        : £ --> ? : false
0xFFE5, // 0xA1EF   YEN SIGN                          : ¥ --> ¥ : true
0xFFE2, // 0xA2CC   NOT SIGN                          : ¬ --> ? : false
0xFF5E, // 0x8FA2B7 TILDE                             : 〜 --> 〜 : true
0xFFE4  // 0x8FA2C3 BROKEN BAR                        : 釗 --> ? : false

trueと出ていれば成功,falseとなっていれば文字破壊です.まず基本ですが,NEC拡張文字(row13)が使えます.次に気になるのは,"ujis→Unicode"の方式で変換された文字は大概使えるのですが,"eucjpms→Unicode"の方式で変換された文字は半分以上破壊されています.

これはどういうことなのでしょうか.EUC_JP_SolarisNEC特殊文字は使えるけれども,Unicode変換ルールはujis寄りということになってしまいます.

同じコードをencoding=EUC_JPで実行した結果とのdiffを以下に示します.

E:\diff>diff EUC_JP.log EUC_JP_Solaris.log
4c4
< 0x3231, // 0x878A of WINDOWS-31J, NEC special(row13). : ㈱ --> ? : false
---
> 0x3231, // 0x878A of WINDOWS-31J, NEC special(row13). : ㈱ --> ㈱ : true

E:\diff>

これは両者の違いは文字集合NEC拡張文字(row13)」を持つか持たないかということだけのようです.

EUC_JP=ujis,EUC_JP_Solaris=eucjpmsという図式でConnector/Jに実装を組み込むように提案しようと考えていましたが,事態はもう少し複雑のようですね.

この図式で実装してしまった場合の影響について別記事で考えたいと思います.