[PHP-dev 1358] Re: PHP 5.2.0 以前と PHP 5.2.1RC1 以降で発生する一部の文字コード変換の非互換について

komura komura @ ma9.seikyou.ne.jp
2007年 1月 25日 (木) 02:50:17 JST


komura です。

私の方が文字コードに対する知識が足りないのでもっと勉強しないと小泉さんが
提案されている妥協策についてはすぐには評価できないのですが、以前のメール
は私の説明が悪かったように思いますので、もう少し詳しく説明してみます。

今回、私が気になったのは、"SJIS" の場合、"\x81\x60" は、PHP 5.2.0 以前では
WAVE DASH(U+301C) に変換されていましたが、PHP 5.2.0RC1 以降では
FULLWIDTH TILDE(U+FF5E) に変換されている点です。
つまり、PHP 5.2.0RC1 以降は、mb_convert_encoding() では WAVE DASH に変換
できなくなっています。

以下のように、PHP 5.2.0 以前でも "SJIS-Win" で変換した場合は、
FULLWIDTH TILDE(U+FF5E) に変換できています。

 $ php-5.2.0    -r 'echo bin2hex( mb_convert_encoding( "\x81\x60", "UTF-16", "SJIS-WIN" ) )'
 ff5e
 $ php-5.2.0    -r 'echo bin2hex( mb_convert_encoding( "\x81\x60", "UTF-16", "SJIS" ) )'
 301c
 $ php-5.2.1RC3 -r 'echo bin2hex( mb_convert_encoding( "\x81\x60", "UTF-16", "SJIS-WIN" ) )'
 ff5e
 $ php-5.2.1RC3 -r 'echo bin2hex( mb_convert_encoding( "\x81\x60", "UTF-16", "SJIS" ) )'
 ff5e

もう少し分かりやすく表にすると以下のようになります。

 (EUC-JP:0xA1C1, SJIS:0x8160) を UTF-16 に変換
 +-----------+-----------+--------------+
 |           | PHP 5.2.0 | PHP 5.2.1RC3 |
 +-----------+-----------+--------------+
 | SJIS      | 301c      | ff5e (**)    |
 +-----------+-----------+--------------+
 | SJIS-win  | ff5e      | ff5e         |
 +-----------+-----------+--------------+
 | EUC-JP    | 301c      | ff5e (**)    |
 +-----------+-----------+--------------+
 | eucJP-win | ff5e      | ff5e         |
 +-----------+-----------+--------------+

参考までに、glibc の iconv では、以下のようになっています。
前に BOM が付いていますが、PHP 5.2.0 以前と同じようです。

 $ iconv --version
 iconv (GNU libc) 2.4
 
 $ echo -e "\x81\x60" | iconv -f SJIS -t UTF-16 | hexdump
 0000000 feff 301c 000a
 0000006
 $ echo -e "\x81\x60" | iconv -f SJIS-WIN -t UTF-16 | hexdump
 0000000 feff ff5e 000a
 0000006
 $ echo -e "\x81\x60" | iconv -f SJIS-OPEN -t UTF-16 | hexdump
 0000000 feff ff5e 000a
 0000006

また、以下の説明などから SJIS(SJIS-win ではない) の場合は、WAVE DASH に
割り当てるのが一般的(PHP 5.2.0 以前のままで良い)だと考えて前のメールを
出したのですが、どうなのでしょうか?

> このように、Windowsでは、Shift_JIS 0x8160(WAVE DASH, 波ダッシュ)が本来
> 割り当てるべき U+301C WAVE DASH(波ダッシュ)ではなく、
> U+FF5E FULLWIDTH TILDE(全角チルダ)に割り当てている。

http://ja.wikipedia.org/wiki/%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5


On Tue, 23 Jan 2007 18:50:14 +0900
Moriyoshi Koizumi <moriyoshi @ at.wakwak.com> wrote:

> ただ、正しいかどうかは別に、下位互換性が損なわれてしまったのは
> 問題ですね。
> 
> そこで、妥協策として、
> 
> 1.  新しい (正しい) マッピングを持つコードセット名として
>     「SJIS-MS」を新設する。eucJP-MS との対照ともなるので
>     名前も「SJIS-Win」と比較してより直感的と思われる。
> 2.  「SJIS-Win」および「SJIS-Open」に関しては、SJIS-Open の
>     コードセットを持つものとして扱う。少なくともこの 2 つの
>     コードセット名が指定された場合はこれまでの挙動を維持する。
> 3.  「Windows-31J」および「MS_Kanji」については
>     「SJIS-MS」のエイリアスとする。
> 4.  「CP932」についての扱いについては次の 2 つの選択肢。
>     a. CP932 = MSCP932 とみなし、SJIS-MS のエイリアスとする。
>        (私はこれがいいです)
>     b. CP932 != MSCP932 とみなし、「MS932」を SJIS-MS の
>        エイリアスとして定義する (Sun Java 方式)。
>        ほかの CPxxxx が MSCP を基準にしているとすれば
>        一貫性が損なわれる危険がある。
> 
> を提案したいと思います。

このあたりの文字コードセットの関係については詳しくありませんが、
いずれはこういった形で整理された方が良いと思います。

ただ、PHP 5.2.1 がリリースされるまであまり時間がないと思いますので、
今回の変更が仕様なのかどうかを確認したかったのです。
仕様ということであれば、アナウンスをした方が混乱が少なくて良いのでは
ないかと思います。

-- 
komura <komura @ ma9.seikyou.ne.jp>


PHP-dev メーリングリストの案内