=readme charset shift-jis LastModified : 2005-08/16 /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Base64 : encode / decode RFC 2045 ftp://ftp.isi.edu/in-notes/rfc2045.txt Written by kerry http://202.248.69.143/~goma/ /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 当ライブラリはモジュールが使えない環境用に書かれたコードです。通常は # eXample use MIME::Base64; $str = "hello world!"; $b64 = encode_base64( $str ); $str = decode_base64( $b64 ); /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Usage # エンコード $b64 = base64'encode( *data ); # デコード $data = base64'decode( *b64 ); # エンコード (置き換え) # $data を符号化したものに置き換える。 # メモリを一定量以上使わない。が、encode() より遅い。 b64'rencode( *data ); # デコード (置き換え) # $b64 を復号化したものに置き換える。 # メモリを一定量以上使わない。が、decode() より遅い。 b64'rdecode( *b64 ); # ファイルを符号化し書き出す $bool = base64'fencode( $infile, $outfile ); # ファイルを復号化し書き出す $bool = base64'fdecode( $infile, $outfile ); $data (*data) -> 符号化したいデータ $b64 (*b64) -> 復号化したいデータ $infile -> 対象ファイル $outfile -> 保存先ファイル $bool -> 失敗時は偽 =cut package base64; sub encode { @encTable = ("A".."Z", "a".."z", 0..9, "+", "/") if !@encTable; (*indata) = shift; $datLen = length $indata; $rLen = 3* 200; $outdata = ""; $tmp = ""; $n = int $datLen/$rLen; $n += $datLen/$rLen <=> $n; for ($i=0; $i<$n; $i++) { $tmp .= substr $indata, $i* $rLen, $rLen; $tmp = to_code(*tmp, *outdata); } $outdata .= enc_mod($tmp); return $outdata; } sub rencode { @encTable = ("A".."Z", "a".."z", 0..9, "+", "/") if !@encTable; (*indata) = shift; $datLen = length $indata; $indata =~ s/(...)/ enc_reg($1) /eg; if ($mod = $datLen % 3) { $indata =~ s/.{$mod}$/ enc_mod(substr $indata, -$mod) /e; } return *indata; } sub enc_reg { @tmp = unpack "C3", shift; $tmp = ($tmp[0]<<16) | ($tmp[1]<<8) | $tmp[2]; return $encTable[ $tmp>>18 ] . $encTable[($tmp>>12) & 0x3f] . $encTable[($tmp>> 6) & 0x3f] . $encTable[ $tmp & 0x3f]; } sub fencode { ($infile, $outfile) = @_; $bufSize = 512; @encTable = ("A".."Z", "a".."z", 0..9, "+", "/") if !@encTable; $buf = ""; open (IN, $infile) or return; binmode IN; open (OUT, "> $outfile") or return; binmode OUT; while (read IN, $buf, $bufSize, length $buf) { $b64 = ""; $buf = to_code(*buf, *b64); print OUT $b64; } print OUT enc_mod($buf); close IN; close OUT; } sub to_code { local (*pdata, *pbuf) = @_; local ($b64tmp, $cnt, $cMod) = (0, 0, ""); foreach (unpack "C*", $pdata) { $b64tmp = ($b64tmp << 8) | $_; if (!(++$cnt%3)) { $pbuf .= $encTable[($b64tmp>>18) & 0x3f] . $encTable[($b64tmp>>12) & 0x3f] . $encTable[($b64tmp>> 6) & 0x3f] . $encTable[ $b64tmp & 0x3f]; } } if ($cnt%3) { $cMod = substr $pdata, -($cnt%3); } return $cMod; } sub enc_mod { local ($dt, $mod) = @_; if (!($mod = length $dt)) { return ""; } local ($n, $c) = 0; $n = ($n<<8) | $_ foreach (unpack "C*", $dt); if ($mod == 1) { $c = $encTable[($n>> 2) & 0x3f] . $encTable[($n<< 4) & 0x3f] . "=="; } else # if ($mod == 2) { $c = $encTable[($n>>10) & 0x3f] . $encTable[($n>> 4) & 0x3f] . $encTable[($n<< 2) & 0x3f] . "="; } return $c; } sub decode { (*indata) = shift; $datLen = length $indata; $rLen = 4* 200; $outdata = ""; $tmp = ""; $n = int $datLen/$rLen; $n += $datLen/$rLen <=> $n; for ($i=0; $i<$n; $i++) { $tmp .= substr $indata, $i* $rLen, $rLen; $tmp = from_code(*tmp, *outdata); } $outdata .= dec_mod($tmp); return $outdata; } sub rdecode { (*indata) = shift; $indata =~ s![^A-Za-z0-9\+/]!!g; $datLen = length $indata; $indata =~ s/(....)/ dec_reg($1) /eg; if ($md = $datLen % 4) { $indata =~ s/.{$md}$/ dec_mod(substr $indata, -$md) /e; } return *indata; } sub fdecode { ($infile, $outfile) = @_; $bufSize= 512; $buf = ""; $b24 = 0; $cnt = 0; open (IN, $infile) or return; binmode IN; open (OUT, "> $outfile") or return; binmode OUT; while (read IN, $buf, $bufSize) { $buf =~ s![^A-Za-z0-9\+/]!!g; $bufMod = substr $buf, -3; $buf =~ tr!A-Za-z0-9\+/!\x00-\x3f!; foreach (unpack "C*", $buf) { $b24 = ($b24 << 6) | $_; if (!(++$cnt % 4)) { $data .= pack "C3", ($b24>>16) & 0xff, ($b24>> 8) & 0xff, $b24 & 0xff; $b24 = 0; } } print OUT $data; $data = ""; } if ($md = $cnt % 4) { print OUT dec_mod(substr $bufMod, -($md)); } close IN; close OUT; } sub from_code { local (*pb64, *pdata) = @_; local ($cnt, $b24, $cMod) = (0, 0, ""); $pb64 =~ s![^A-Za-z0-9\+/]!!g; if ($mod = length($pb64) % 4) { $cMod = substr $pb64, -($mod % 4); } $pb64 =~ tr!A-Za-z0-9\+/!\x00-\x3f!; foreach (unpack "C*", $pb64) { $b24 = ($b24 << 6) | $_; if (!(++$cnt%4)) { $pdata .= pack "C3", ($b24>>16) & 0xff, ($b24>> 8) & 0xff, $b24 & 0xff; $b24 = 0; } } return $cMod; } sub dec_reg { $tmp = shift; $tmp =~ tr!A-Za-z0-9\+/!\x00-\x3f!; $b24 = 0; $b24 = ($b24<<6) | $_ foreach (unpack "C*", $tmp); return pack "C3", ($b24>>16) & 0xff, ($b24>> 8) & 0xff, $b24 & 0xff; } sub dec_mod { local ($dt, $mod) = @_; if (!($mod = length $dt)) { return ""; } local ($24, $c) = (0, 0); $dt =~ tr!A-Za-z0-9\+/!\x00-\x3f!; $b24 = ($b24<<6) | $_ foreach (unpack "C*", $dt); if ($mod == 3) { $c = pack "C2", ($b24>>10) & 0xff, ($b24>> 2) & 0xff; } else { # $mod == 2 $c = pack "C", ($b24>> 4) & 0xff; } return $c; } &arg_check if @ARGV; sub arg_check { $| = 1; $switch_enc_s = "/e"; $switch_dec_s = "/d"; $switch_enc_f = "/ef"; $switch_dec_f = "/df"; if ($ARGV[0] =~ m!^/?(\?|help)$!i ) { &arg_help; } elsif (@ARGV<2) { arg_help('引数が足りません'); } elsif ($ARGV[0] =~ m|^$switch_enc_s$|i) { $atmp = encode(\$ARGV[1]); print $atmp; } elsif ($ARGV[0] =~ m|^$switch_dec_s$|i) { $atmp = decode(\$ARGV[1]); print $atmp; } elsif ($ARGV[0] =~ m|^$switch_enc_f$|i) { &arg_fcheck; if (!fencode($arg[1], $ARGV[2])) { arg_help('ファイルを開けません'); } } elsif ($ARGV[0] =~ m|^$switch_dec_f$|i) { &arg_fcheck; if (!fdecode($ARGV[1], $ARGV[2])) { arg_help('ファイルを開けません'); } } elsif ($ARGV[0] =~ m|^(/.+)|) { arg_help(sprintf '"%s" というオプションはありません', $1); } else { arg_help('エラー'); } } sub arg_fcheck { if (-f $ARGV[1]) { if ($ARGV[2] eq "") { $ARGV[2] = $ARGV[1] . ".base64"; } } else { arg_help( sprintf '"%s" は存在しません', $ARGV[1]); } } sub arg_help { if (@_) { printf "===================================\n" . "* ERROR\n" . " %s\n" . "===================================\n", shift; } print <<_OUT_; Usage; * Encode $switch_enc_s "string" * Decode $switch_dec_s "encodedString" * File Encode $switch_enc_f "inFileName" "outFileName" * File Decode $switch_dec_f "inFileName" "outFileName" _OUT_ exit; } 1;