[pgsql-jp: 37938] Re: EUC_JP を UTF8 に変換するには

MORIYAMA Masayuki moriyama @ miraclelinux.com
2007年 1月 12日 (金) 13:05:02 JST


森山(将之)です。

# ML の過去ログ読んでいたら、他にも森山さんがいましたので…

Morita Kazuro wrote:
> 森田です。お世話になっております。
> 
>>  「昔からある単純なアルゴリズム」の定義が違うのかもしれませんね。私は、
>> 計算だけで変換できるレベルのアルゴリズムを言っていました。古すぎるのかも。
> 
> あれれ、私も単純に計算しているだけでした。

単純な計算による変換では、EUC の 1 バイト目は、95区が 0xFF、96区〜120区
が、0x00〜0x18 となって、EUC->SJIS の逆変換で元に戻らなくなりますよ。

> それで、昔のソースを調べてみました。よく見たら、自分流の変換は外字に対しては
> 正しい EUC に変換しているわけではありませんでした。じゃーなんで動いていたの? 
> と思ってさらに見たら、少なくともPostgreSQLが保存した文字列と同じ物を返して
> くれる限りは、自分流の逆変換によって元に戻ることは保証されていました。

EUC->SJIS で元に戻るという事は、SJIS->EUC の変換で、95区が 0xFF、96区
〜120区が 0x80〜0x98 という風に変換しているのでしょう。(マルチバイト文字
の時には、強制的に、最上位ビットを 1 にしている。)

SJIS->JIS 変換してから、マルチバイト文字の各バイトの最上位ビットを1にし
て EUC に変換するとこうなりますね。

そして、EUC->SJIS の変換では、EUC->JIS->SJIS という具合に、一旦 JIS に変
換してから SJIS へ変換していると推測されます。

その際、JIS への変換では 1区〜95区 が 0x21〜0x7F、96区〜120区が
0x80〜0x98 となるように変換する事で、JIS->SJIS の変換で、95区〜120区が復
元されたというわけです。

次のような変換がなされていたという事が推測できます。

 区-点  SJIS    JIS     EUC     JIS     SJIS
 01-01  8140 -> 2121 -> A1A1 -> 2121 -> 8140
   :      :       :       :      :       :
 62-94  9FFC -> 5E7E -> DEFE -> 5E7E -> 9FFC
 63-01  E040 -> 5F21 -> DFA1 -> 5F21 -> E040
   :      :       :       :      :       :
 94-94  EFFC -> 7E7E -> FEFE -> 7E7E -> EFFC
 95-01  F040 -> 7F21 -> FFA1 -> 7F21 -> F040
   :      :       :       :      :       :
 95-94  F0FC -> 7FFE -> FFFE -> 7FFE -> F0FC
 96-01  F140 -> 8021 -> 80A1 -> 8021 -> F140
   :      :       :       :      :       :
120-94  FCFC -> 987E -> 98FE -> 987E -> FCFC

こういった特殊な変換は、一般性が無いので御注意ください。

特に、95区の扱いが微妙なので、意図せずに96区〜120区が変換できるように
なっていた場合、95区は変換できないという事は十分に考えられます。

> PostgreSQL の SQL_ASCII が文字コードが正しいかどうかに対して一切口出しをしな
> いのが、動いているように見えていた原因でした。でも、この性質は考えようによって
> は便利かもしれませんね。

(意図している/していないに関わらず)トリッキーな事をしていると 、後々、苦
労する事になるので、御注意くださいね。

自分が苦労するならまだしも、他の人に引き継いだ場合、引き継いだ人が泣きを
見る事になるので、その辺の所も考慮しておいてあげてくださいね。

--
森山 将之 <msyk @ mtg.biglobe.ne.jp>




pgsql-jp メーリングリストの案内