プロが教える店舗&オフィスのセキュリティ対策術

電子メールの件名やあて先など、日本語を使うと、
インターネットヘッダ内では、例えば以下のような
ASCII文字にエンコードされていますが、
=?iso-2022-jp?Q?=1B$BEE;R%a!<%k$N7oL>?=
これはどんな規則でエンコードされているのでしょうか。
つまり、メーラを使わずに手操作でデコードしたいのですが、
どのような手続きをとれば、日本語(シフトJISなど)に
変換できるのでしょうか?
あるいは、フリーの変換ソフトなどがあれば、教えていただきたく
思っています。

A 回答 (2件)

デコードするなら The Web KANZAKI の


文字化けしたメールの修復
http://kanzaki.com/docs/jis-recover.html


どのようにエンコードされているのかは、とほほの WWW 入門の
CGI から送信するメールのヘッダに日本語を用いるには
http://tohoho.wakusei.ne.jp/wwwxx006.htm

が役に立つと思います。

この回答への補足

ありがとうございます。特に後者のサイトは、役に立ちました。
けっきょく、base64なわけですね。納得です。
大量のメールを自動的に変換したく思っているのですが、
Cで書かれているbase64のデコーダのソースプログラム、
なければPerlでもかまわないのですが、そんなものは
どこかで手に入らないものでしょうか。

補足日時:2002/03/08 13:15
    • good
    • 0

 私の場合、pascal ですが、こんな関数でシフトJISに直しています。

(DOS 版です。)
 自己流ソフトでスミマセン。正しいという保証はありません。
 なお、このサイトでは、インデントが無視されてしまうので、とても見にくくなっています。

function mmdecode(inrec:string):string; (* MIMEをシフトJISコードに変換 *)
(* MIME decode 参考文献=日経バイト No.177 1998.5 pp.294-297 *)

function mmconv(mm:string):string;
const BASE64=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const kin=#$1B+'$B'; kout1=#$1B+'(J'; kout2=#$1B+'(B';
var jis,sjis,s:string;
m1,m2,m3,m4,n1,n2,n3:byte;
nchar,loc,i:integer;
begin
jis:='';
(* JIS コードに変換 *)
while mm<>'' do
begin
m1:=pos(mm[1],BASE64)-1; m2:=pos(mm[2],BASE64)-1;
m3:=pos(mm[3],BASE64)-1; m4:=pos(mm[4],BASE64)-1;
(* writeln('m1=',m1,' m2=',m2,' m3=',m3,' m4=',m4); *)
if mm[3]='=' then nchar:=2
else if mm[4]='=' then nchar:=3
else nchar:=4;
n1:=m1*4+m2 div 16;
if nchar>2 then n2:=(m2 mod 16)*16+m3 div 4;
if nchar>3 then n3:=(m3 mod 4)*64+m4;
(* writeln('n1=',n1,' n2=',n2,' n3=',n3); *)
if nchar=2 then jis:=jis+chr(n1)
else if nchar=3 then jis:=jis+chr(n1)+chr(n2)
else jis:=jis+chr(n1)+chr(n2)+chr(n3);
delete(mm,1,4);
end;
(* write('jis='); for i:=1 to length(jis) do write(hex(ord(jis[i])),' '); *)
(* JIS コードの内、漢字コードをシフトJISにする *)
sjis:='';
while jis<>'' do
begin
loc:=pos(kin,jis); (* writeln('kin の位置=',loc); *)
if loc=0 then
begin
sjis:=sjis+jis; jis:='';
end
else
begin
sjis:=sjis+copy(jis,1,loc-1); delete(jis,1,loc+2);
loc:=pos(kout1,jis);
if loc=0 then loc:=pos(kout2,jis);
if loc=0 then writeln('error kout なし');
s:=copy(jis,1,loc-1);
(* write('s='); for i:=1 to length(s) do write(hex(ord(s[i])),' '); *)
sjis:=sjis+jis2shift_jis(s); delete(jis,1,loc+2);
end;
end;
(* writeln('mmconv の結果=',sjis); *)
mmconv:=sjis;
end;

(* mmdecode 本体 *)
const key1='=?ISO-2022-JP?B?'; key2='=?iso-2022-jp?B?'; keyend='?=';
var result,mm:string;
var loc:integer;
begin
result:='';
while inrec<>'' do
begin
loc:=pos(key1,inrec); if loc=0 then loc:=pos(key2,inrec);
if loc=0 then
begin
result:=result+inrec; inrec:='';
end
else
begin
result:=result+copy(inrec,1,loc-1); delete(inrec,1,loc+15);
loc:=pos(keyend,inrec);
if loc=0 then
begin
writeln('error 終わり「',keyend,'」が存在しない'); inrec:='';
end
else
begin
mm:=copy(inrec,1,loc-1); delete(inrec,1,loc+1);
(* writeln('mmconv に渡す文字列=',mm); *)
if (length(mm) mod 4)<>0 then
writeln('error BASE64 の長さが4の倍数でない')
else result:=result+mmconv(mm);
end;
end;
end;
mmdecode:=result;
end;
    • good
    • 0
この回答へのお礼

やはりご自身で変換する必要があり、
独自のプログラムを書いたのでしょうか。
ご親切にありがとうございました。
7,8年前、僕もPascalを使っていたのですが、
Cに乗り換えて以来、すっかり忘れて、コンパイラすらない状況です。
頑張って、解読し、Cに書き直してみます。

お礼日時:2002/03/23 10:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!