2009/01/30 金 00:14
Shift_JIS ←→ ISO-2022-JP 変換スクリプト
今、きき☆彡はウェブサイトをいろいろ変更しているところです。
その中でいまやっているのがメッセージ送信のページ&CGI変更です。
そこでMIMEエンコードというのが必要になってきたのですが公開されているものには満足のいくものがない・・・
ということで自分で作っちゃいました♪
ついでにコード変換機能もつけています(^-^;
ソースを見たい人は続きをどうぞ~♪
【02/26追記】
プログラムにいくつか間違いがあってiso→Shift_JISの変換すべてとShift_JISでコードE040以降の文字が正しく変換されませんでした(汗
修正しておきます~(>_<) (赤字のところ)
あぁ・・やはりちゃんとチェックをしておかないとだめですなぁ・・;
その中でいまやっているのがメッセージ送信のページ&CGI変更です。
そこでMIMEエンコードというのが必要になってきたのですが公開されているものには満足のいくものがない・・・
ということで自分で作っちゃいました♪
ついでにコード変換機能もつけています(^-^;
ソースを見たい人は続きをどうぞ~♪
【02/26追記】
プログラムにいくつか間違いがあってiso→Shift_JISの変換すべてとShift_JISでコードE040以降の文字が正しく変換されませんでした(汗
修正しておきます~(>_<) (赤字のところ)
あぁ・・やはりちゃんとチェックをしておかないとだめですなぁ・・;
#--------------------------------
# Shift_JIS <-> ISO-2022-JP変換ライブラリ
# (JIS X 0208-1983 と ASCII のみ対応)
# by きき☆彡 2009/02/26
#--------------------------------
#
# ●&Kicode::to_iso( Shift_JIS文字列 )
# ISO-2022-JPに変換した文字列を返す
#
# ●&Kicode::from_iso( ISO-2022-JP文字列 )
# Shift_JISに変換した文字列を返す
#
# ●&Kicode::to_mime( ISO-2022-JP文字列 )
# mime形式に変換した文字列を返す
# 例:
# &to_mime('Subject: '.&to_iso('Little Twin Starsのグッズを買ったよ~☆'));
#
package Kicode;
$b64c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$encb = '=?ISO-2022-JP?B?';
$ence = '?=';
$fullvoice = 'ウカキクケコサシスセソタチツテトハヒフヘホ';
$semivoice = 'ハヒフヘホ';
@halfmap = (
[0xa1, 0x2123],
[0xa2, 0x2156],
[0xa3, 0x2127],
[0xa4, 0x2122],
[0xa5, 0x2126],
[0xa6, 0x2572],
[0xa7, 0x2521],
[0xa8, 0x2523],
[0xa9, 0x2525],
[0xaa, 0x2527],
[0xab, 0x2529],
[0xac, 0x2563],
[0xad, 0x2565],
[0xae, 0x2567],
[0xaf, 0x2543],
[0xb0, 0x213c],
[0xb1, 0x2522],
[0xb2, 0x2524],
[0xb3, 0x2526],
[0xb4, 0x2528],
[0xb5, 0x252a],
[0xb6, 0x252b],
[0xb7, 0x252d],
[0xb8, 0x252f],
[0xb9, 0x2531],
[0xba, 0x2533],
[0xbb, 0x2535],
[0xbc, 0x2537],
[0xbd, 0x2539],
[0xbe, 0x253b],
[0xbf, 0x253d],
[0xc0, 0x253f],
[0xc1, 0x2541],
[0xc2, 0x2544],
[0xc3, 0x2546],
[0xc4, 0x2548],
[0xc5, 0x254a],
[0xc6, 0x254b],
[0xc7, 0x254c],
[0xc8, 0x254d],
[0xc9, 0x254e],
[0xca, 0x254f],
[0xcb, 0x2552],
[0xcc, 0x2555],
[0xcd, 0x2558],
[0xce, 0x255b],
[0xcf, 0x255e],
[0xd0, 0x255f],
[0xd1, 0x2560],
[0xd2, 0x2561],
[0xd3, 0x2562],
[0xd4, 0x2564],
[0xd5, 0x2566],
[0xd6, 0x2568],
[0xd7, 0x2569],
[0xd8, 0x256a],
[0xd9, 0x256b],
[0xda, 0x256c],
[0xdb, 0x256d],
[0xdc, 0x256f],
[0xdd, 0x2573],
[0xde, 0x212b],
[0xdf, 0x212c]
);
sub from_iso{
local($a,$l,$m,$r,$s,$t,$u,$v,$x);
$l = length($s = $_[0]);
$r = '';
$m = 0;
for($a = 0;$a < $l;++$a){
$t = substr($s,$a,3);
if($t =~ /^\e\$[\@B]$/){
$m = 1;
$a += 3;
}elsif($t =~ /^\e\([BJ]$/){
$m = 0;
$a += 3;
}
($t,$u) = split(//,substr($s,$a,2));
if($m && $a < $l-1){
($t,$u) = unpack('CC',$t.$u);
$x = $t;
$v = int(($x-33)/2);
$r .= pack('C',$v+($v<31 ? 129 : 193));
$r .= pack('C',$u+($x & 1 ? ($u < 96 ? 31 : 32) : 126));
$a++;
}else{
$r .= $t;
}
}
return $r;
}
sub to_iso{
local($a,$l,$m,$r,$s,$t,$u,$x);
$l = length($s = $_[0]);
$r = '';
$m = 0;
for($a = 0;$a < $l;++$a){
($t,$u) = split(//,substr($s,$a,2));
if($a < $l-1 && $t =~ /^[\x81-\x9f\xa1-\xdf\xe0-\xff]$/){
if(!$m){
$m = 1;
$r .= "\e\$B";
}
($t,$u) = unpack('CC',$t.$u);
if($t>=0xa1 && $t<=0xdf){
$x = 0;
if($u == 0xde && index($fullvoice,pack('C',$t),0) != -1){
$x = $t == 0xb3 ? 0x4e : 1;
}elsif($u == 0xdf && index($semivoice,pack('C',$t),0) != -1){
$x = 2;
}
$r .= pack('n',$halfmap[$t-0xa1][1]+$x);
++$a if($x != 0);
}else{
--$u if($u > 128);
$x = 0;
if($u >= 158){
$x = 1;
$u -= 94;
}
$u -= 0x1f;
$t = ($t >= 224 ? $t-64 : $t)*2-225+$x;
$r.= pack('CC',$t,$u);
++$a;
}
}else{
if($m){
$m = 0;
$r .= "\e(B";
}
if(($p=ord($t))<128){
$r .= $t;
}
}
}
return $r;
}
sub to_mime{
local($a,$b,$c,$d,$e,$f1,$f2,$l,$lm,$m,$r1,$r2);
$lm = 78;
$l = length($_[0]);
$r1 = '';
$r2 = '';
$f1 = 0;
$f2 = 0;
$m = 0;
for($a = 0;$a < $l;){
if($m == 0){
for(;$a<$l && ($d=substr($_[0],$a,1)) ne "\e";++$a){
$d = ' ' if($d eq "\n");
$r2 .= $d;
++$f2;
if($f1+$f2>$lm){
if($f1<6){
$b = $lm-$r1;
$r1 .= substr($r2,0,$b);
$f2 = length($r2)-$b;
$r2 = substr($r2,$b,$f2);
}
$r1 .= "\n ";
$f1 = 1;
}
if($d eq ' '){
$r1 .= $r2;
$r2 = '';
$f1 += $f2;
$f2 = 0;
}
}
$r1 .= $r2;
$f1 += $f2;
}elsif($m == 1){
if($lm-$f1<26){
$r1 .= "\n ";
$f1 = 1;
}
$r2 = "\e\$B";
$f2 = 6;
for($b = $a;$b<$l;$b+=2){
$d = substr($_[0],$b,2);
last if($d =~ /^\e/);
$f2 += 2;
$c = int(($f2+2)/3)*4+18;
if($f1+$c>$lm){
if($f1<20){
$r1 .= $encb.&to_b64($r2."\e(B").$ence;
$r2 = "\e\$B";
$f2 = 8;
}
$r1 .= "\n ";
$f1 = 1;
}
$r2 .= $d;
}
$a = $b;
if($f2>6){
$r1 .= $encb.&to_b64($r2."\e(B").$ence;
$f1 += $c;
}
}else{
for(;$a<$l && substr($_[0],$a,1) ne "\e";++$a){
}
}
$r2 = '';
$f2 = 0;
if($a<$l){
$d = substr($_[0],$a,3);
if($d =~ /^([^\e]|\e\([BJ])/){
$m = 0;
}elsif($d =~ /^\e\$[\@B]/){
$m = 1;
}else{
$m = 2;
}
$a += 3;
}
}
return $r1;
}
sub to_b64{
local($a,$d,$l,$p,$r,@s,@t,$v);
$v = $_[0]."\x00\x00";
$l = length($_[0]);
$r = '';
for($p = 0;$p < $l;$p+=3){
@t = unpack('C3',substr($v,$p,3));
@s = (($t[0] & 252) >> 2,(($t[0] & 3) << 4) + (($t[1] & 240) >> 4),(($t[1] & 15) << 2) + (($t[2] & 192) >> 6),$t[2] & 63);
$d = $p+3;
for($a = 0;$a <= 3;++$a){
if($p + $a > $l){
$r .= '=';
}else{
$r .= substr($b64c,$s[$a],1);
}
}
}
return $r;
}
sub from_b64{
local($a,$d,$l,$p,$r,@t,$v);
$v = $_[0];
$v =~ s/[^\+\/\=0-9A-Za-z]//g;
if($l % 4 != 0 || $v !~ /^[^\=]*\={0,2}$/){
return undef;
}
$l = length($v) if (($l = index($v,'=',0)) == -1);
$v =~ s/\=/A/g;
$r = '';
for($p = 0;$p < $l;$p+=4){
@t = ();
for($a = 0;$a < 4;++$a){
push(@t,index($b64c,substr($v,$p+$a,1),0));
}
$s = pack('C3',($t[0] << 2) + (($t[1] & 48) >> 4),(($t[1] & 15) << 4) + (($t[2] & 60) >> 2),(($t[2] & 3) << 6) + $t[3]);
if(($d = $l - $p) < 4){
$r .= substr($s,0,$d - 1);
}else{
$r .= $s;
}
}
return $r;
}
1;
あ、スクリプトの文字コードはShift_JISにしてくださいね(;^▽^A
しっかし、メールヘッダの仕様ってややこしい・・><
コメント☆