• ベストアンサー

インターネットヘッダ内の日本語のエンコード/デコード

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

質問者が選んだベストアンサー

  • ベストアンサー
  • MtHill
  • ベストアンサー率68% (17/25)
回答No.1

デコードするなら The Web KANZAKI の 文字化けしたメールの修復 http://kanzaki.com/docs/jis-recover.html どのようにエンコードされているのかは、とほほの WWW 入門の CGI から送信するメールのヘッダに日本語を用いるには http://tohoho.wakusei.ne.jp/wwwxx006.htm が役に立つと思います。

JF1Msf
質問者

補足

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

その他の回答 (1)

  • ogx
  • ベストアンサー率25% (32/125)
回答No.2

 私の場合、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;

JF1Msf
質問者

お礼

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

関連するQ&A