細かきこと

書いたり書かなかったり

文字コード変換 (PHPとPerlについて)

後でまとめるが。。。

sjisの8160(波ダッシュ、WAVE DASH)は下記のユニコードだと2つにマッピングされうる。
FULLWIDTH TILDE(U+FF5E, EFBD9E)
WAVE DASH(U+301C, E3809C)

phpのmb_convert_stringで8160をSJISあるいはsjis-win(cp932)からUTF-8に。

php > echo mb_convert_encoding("\x81\x60",'UTF-8', 'SJIS');
〜
php > echo mb_convert_encoding("\x81\x60",'UTF-8', 'sjis-win');
〜
php > echo bin2Hex(mb_convert_encoding("\x81\x60",'UTF-8', 'sjis-win'));
efbd9e
php > echo bin2Hex(mb_convert_encoding("\x81\x60",'UTF-8', 'SJIS'));
e3809c

php > echo "\xef\xbd\x9e";
〜
php > echo "\xe3\x80\x9c";
〜
php > echo bin2Hex("\xef\xbd\x9e");
efbd9e
php > echo bin2Hex("\xe3\x80\x9c");
e3809c

mb_convert_encodingでfromにsjis-winを指定するとutf-8的にWAVE DASHになって、SJISを指定するとutf-8的にFULLWIDTH TILDEと変換される。
てか、MACで見ると同じように見えるんだな。
コードでみないとわからん。。。


perl

se utf8;
use Test::More;
use Encode;
plan 'no_plan';
my $wave_dash_sjis = "\x81\x60";

my $utf8_1 ="\xe3\x80\x9c";
my $utf8_2 ="\xef\xbd\x9e";
Encode::from_to($wave_dash_sjis, 'SJIS', 'utf8');
$wave_dash_sjis =~ s/(.)/sprintf('%X', ord($1))/eg;
print $wave_dash_sjis , "\n";
is $wave_dash_sjis, 'E3809C';
$wave_dash_sjis = "\x81\x60";
Encode::from_to($wave_dash_sjis, 'cp932', 'utf8');
$wave_dash_sjis =~ s/(.)/sprintf('%X', ord($1))/eg;
print $wave_dash_sjis , "\n";
is $wave_dash_sjis, 'EFBD9E';

結果

E3809C
ok 1
EFBD9E
ok 2
1..2

Encodeでもmb_convert_encoding同様cp932だとutf-8的にWAVE DASHになって、SJISを指定するとutf-8的にFULLWIDTH TILDEと変換される。

シフトJISのWAVE DASHをutf-8でもWAVE DASHにするには、SJISで変換すると。
ただ、windowsだと変に見えると。(波が逆)

参考

http://blog.rodoku.net/pages/user/m/article?article_id=27831265&page=2
http://blog.as-is.net/2003/05/utf-8.html