=readme charset shift-jis LastModified : 2005-08/20 /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ RIPEMD-160 http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html Written by kerry http://202.248.69.143/~goma/ /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Usage; * 文字列のハッシュ値を得る # RIPEMD-128 $rmd128hex = ripemd'rmd128( $str ); # RIPEMD-160 $rmd160hex = ripemd'rmd160( $str ); # RIPEMD-256 $rmd256hex = ripemd'rmd256( $str ); # RIPEMD-320 $rmd320hex = ripemd'rmd320( $str ); * ファイルのハッシュ値を得る # RIPEMD-128 $rmd128hex = ripemd'rmd128f( $file ); # RIPEMD-160 $rmd160hex = ripemd'rmd160f( $file ); # RIPEMD-256 $rmd256hex = ripemd'rmd256f( $file ); # RIPEMD-320 $rmd320hex = ripemd'rmd320f( $file ); ------------------------------------------------------------------------- * 返り値 通常は以下( 16進数に整形されたハッシュ値が返ってくる) $hexHash = ripemd'rmd160( $str ); 整形前の値が欲しい時は配列で受け取れる @decHashz = ripemd'rmd128( $str ); # e.g. $binHash = pack("N*", @decHashz); ファイルを開けなかった場合は "error" という文字列が返る /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ * 参考 http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html http://www.esat.kuleuven.ac.be/~bosselae/ripemd/rmd128.txt http://www.esat.kuleuven.ac.be/~bosselae/ripemd/rmd256.txt http://www.esat.kuleuven.ac.be/~bosselae/ripemd/rmd320.txt =cut package ripemd; sub rmd128 { rmdInit(128); rmdFinish( rmdStr(shift) ) } sub rmd160 { rmdInit(160); rmdFinish( rmdStr(shift) ) } sub rmd256 { rmdInit(256); rmdFinish( rmdStr(shift) ) } sub rmd320 { rmdInit(320); rmdFinish( rmdStr(shift) ) } sub rmd128f { rmdInit(128); rmdFinish( rmdFile(shift) ) } sub rmd160f { rmdInit(160); rmdFinish( rmdFile(shift) ) } sub rmd256f { rmdInit(256); rmdFinish( rmdFile(shift) ) } sub rmd320f { rmdInit(320); rmdFinish( rmdFile(shift) ) } sub rmd128r { rmdInit(128); rmdFinish( rmdStrr(shift) ) } sub rmd160r { rmdInit(160); rmdFinish( rmdStrr(shift) ) } sub rmd256r { rmdInit(256); rmdFinish( rmdStrr(shift) ) } sub rmd320r { rmdInit(320); rmdFinish( rmdStrr(shift) ) } sub rmdFinish { if ($_[0] eq "error") { return wantarray? @_: shift; } $state[$_] = toBigEndian($state[$_]) for 0..$#state; return wantarray ? @state : sprintf "%08x" x @state, @state; } sub rmdStr { ($indata, $dataLen) = @_; $dataLen = length $indata if !$dataLen; $indata .= padding($dataLen); $ri = length ($indata) / $blockLen; for (0..$ri-1) { $block = substr $indata, $blockLen* $_, $blockLen; @x = unpack "V16", $block; &round; } } sub rmdFile { $file = shift; open (IN, $file) or return "error"; binmode IN; $fSize = -s IN; $ri = int ($fSize / $blockLen); while ($ri--) { read IN, $block, $blockLen; @x = unpack "V16", $block; &round; } read IN, $block, $blockLen; close IN; rmdStr($block, $fSize); } sub rmdStrr # if ref shift { *pstr = shift; $len = length $pstr; $ri = int ($len / $blockLen); for (0..$ri-1) { $block = substr $pstr, $blockLen* $_, $blockLen; @x = unpack "V16", $block; &round; } if ($len % $blockLen) { $block = substr $pstr, -($len % $blockLen); } else { $block = ""; } rmdStr($block, $len); } sub padding { $len = shift; $md = $len % $blockLen; $padLen = 8; if ($md>= $blockLen- $padLen) { $md = $blockLen- ($md % $padLen); } else { $md = $blockLen- $padLen- $md; } $pad = "\x80". "\x00" x ($md-1); $len *= $padLen; $pad .= pack "V2", $len & 0xffffffff, $len / 0xffffffff; } sub mod { $_[0] % 4294967296 } sub rotl { ($_[0] << $_[1]) | ($_[0] >> (32 - $_[1])) } sub toBigEndian { ($_[0] & 0x000000ff) << 24 | ($_[0] & 0x0000ff00) << 8 | ($_[0] & 0x00ff0000) >> 8 | ($_[0] & 0xff000000) >> 24 ; } sub k { if ($_[0] < 16) { 0 } elsif ($_[0] < 32) { 0x5A827999 } elsif ($_[0] < 48) { 0x6ED9EBA1 } elsif ($_[0] < 64) { 0x8F1BBCDC } elsif ($_[0] < 80) { 0xA953FD4E } } sub k2 { if ($_[0] < 16) { 0x50A28BE6 } elsif ($_[0] < 32) { 0x5C4DD124 } elsif ($_[0] < 48) { 0x6D703EF3 } elsif ($_[0] < 64) { $_[1] ? 0x7A6D76E9 : 0 } elsif ($_[0] < 80) { 0 } } sub f { if ($_[3] < 16) { $_[0] ^ $_[1] ^ $_[2] } elsif ($_[3] < 32) { ($_[0] & $_[1]) | (~$_[0] & $_[2]) } elsif ($_[3] < 48) { ($_[0] | ~$_[1]) ^ $_[2] } elsif ($_[3] < 64) { ($_[0] & $_[2]) | ($_[1] & ~$_[2]) } elsif ($_[3] < 80) { $_[0] ^ ($_[1] | ~$_[2]) } } sub rmd128roundz { @tmpState1 = @tmpState2 = @state; for $n (0..63) { $tmp = mod( $tmpState1[0] + f(@tmpState1[1..3] , $n) + $x[ $r[$n] ] + k($n) ); $tmp = rotl( $tmp, $s[$n] ); $tmpState1[0] = $tmpState1[3]; $tmpState1[3] = $tmpState1[2]; $tmpState1[2] = $tmpState1[1]; $tmpState1[1] = $tmp; $tmp = mod( $tmpState2[0] + f(@tmpState2[1..3] , 63-$n) + $x[ $r2[$n] ] + k2($n) ); $tmp = rotl( $tmp, $s2[$n] ); $tmpState2[0] = $tmpState2[3]; $tmpState2[3] = $tmpState2[2]; $tmpState2[2] = $tmpState2[1]; $tmpState2[1] = $tmp; } $tmp= $state[1] + $tmpState1[2] + $tmpState2[3]; $state[1] = mod( $state[2] + $tmpState1[3] + $tmpState2[0] ); $state[2] = mod( $state[3] + $tmpState1[0] + $tmpState2[1] ); $state[3] = mod( $state[0] + $tmpState1[1] + $tmpState2[2] ); $state[0] = mod( $tmp ); } sub rmd256roundz { @tmpState1 = @state[0..3]; @tmpState2 = @state[4..7]; for $n (0..63) { $tmp = mod( $tmpState1[0] + f(@tmpState1[1..3] , $n) + $x[ $r[$n] ] + k($n) ); $tmp = rotl( $tmp, $s[$n] ); $tmpState1[0] = $tmpState1[3]; $tmpState1[3] = $tmpState1[2]; $tmpState1[2] = $tmpState1[1]; $tmpState1[1] = $tmp; $tmp = mod( $tmpState2[0] + f(@tmpState2[1..3] , 63-$n) + $x[ $r2[$n] ] + k2($n) ); $tmp = rotl( $tmp, $s2[$n] ); $tmpState2[0] = $tmpState2[3]; $tmpState2[3] = $tmpState2[2]; $tmpState2[2] = $tmpState2[1]; $tmpState2[1] = $tmp; if ($n == 15) { ($tmpState1[0], $tmpState2[0]) = ($tmpState2[0], $tmpState1[0]) } elsif ($n == 31) { ($tmpState1[1], $tmpState2[1]) = ($tmpState2[1], $tmpState1[1]) } elsif ($n == 47) { ($tmpState1[2], $tmpState2[2]) = ($tmpState2[2], $tmpState1[2]) } elsif ($n == 63) { ($tmpState1[3], $tmpState2[3]) = ($tmpState2[3], $tmpState1[3]) } } $state[0] = mod($state[0] + $tmpState1[0]); $state[1] = mod($state[1] + $tmpState1[1]); $state[2] = mod($state[2] + $tmpState1[2]); $state[3] = mod($state[3] + $tmpState1[3]); $state[4] = mod($state[4] + $tmpState2[0]); $state[5] = mod($state[5] + $tmpState2[1]); $state[6] = mod($state[6] + $tmpState2[2]); $state[7] = mod($state[7] + $tmpState2[3]); } sub rmd160roundz { @tmpState1 = @tmpState2 = @state; for $n (0..79) { $tmp = mod($tmpState1[0] + f(@tmpState1[1..3] , $n) + $x[ $r[$n] ] + k($n)); $tmp = mod( rotl( $tmp, $s[$n] ) + $tmpState1[4] ); $tmpState1[0] = $tmpState1[4]; $tmpState1[4] = $tmpState1[3]; $tmpState1[3] = rotl($tmpState1[2] , 10); $tmpState1[2] = $tmpState1[1]; $tmpState1[1] = $tmp; $tmp = mod( $tmpState2[0] + f(@tmpState2[1..3] , 79-$n) + $x[ $r2[$n] ] + k2($n, 1) ); $tmp = mod( rotl( $tmp, $s2[$n] ) + $tmpState2[4] ); $tmpState2[0] = $tmpState2[4]; $tmpState2[4] = $tmpState2[3]; $tmpState2[3] = rotl($tmpState2[2] , 10); $tmpState2[2] = $tmpState2[1]; $tmpState2[1] = $tmp; } $tmp= $state[1] + $tmpState1[2] + $tmpState2[3]; $state[1] = mod($state[2] + $tmpState1[3] + $tmpState2[4]); $state[2] = mod($state[3] + $tmpState1[4] + $tmpState2[0]); $state[3] = mod($state[4] + $tmpState1[0] + $tmpState2[1]); $state[4] = mod($state[0] + $tmpState1[1] + $tmpState2[2]); $state[0] = mod($tmp); } sub rmd320roundz { @tmpState1 = @state[0..4]; @tmpState2 = @state[5..9]; for $n (0..79) { $tmp = mod( $tmpState1[0] + f(@tmpState1[1..3] , $n) + $x[ $r[$n] ] + k($n) ); $tmp = mod( rotl( $tmp, $s[$n] ) + $tmpState1[4] ); $tmpState1[0] = $tmpState1[4]; $tmpState1[4] = $tmpState1[3]; $tmpState1[3] = rotl($tmpState1[2] , 10); $tmpState1[2] = $tmpState1[1]; $tmpState1[1] = $tmp; $tmp = mod( $tmpState2[0] + f(@tmpState2[1..3] , 79-$n) + $x[ $r2[$n] ] + k2($n, 1) ); $tmp = mod( rotl( $tmp, $s2[$n] ) + $tmpState2[4] ); $tmpState2[0] = $tmpState2[4]; $tmpState2[4] = $tmpState2[3]; $tmpState2[3] = rotl($tmpState2[2] , 10); $tmpState2[2] = $tmpState2[1]; $tmpState2[1] = $tmp; if ($n == 15) { ($tmpState1[1], $tmpState2[1]) = ($tmpState2[1], $tmpState1[1]) } elsif ($n == 31) { ($tmpState1[3], $tmpState2[3]) = ($tmpState2[3], $tmpState1[3]) } elsif ($n == 47) { ($tmpState1[0], $tmpState2[0]) = ($tmpState2[0], $tmpState1[0]) } elsif ($n == 63) { ($tmpState1[2], $tmpState2[2]) = ($tmpState2[2], $tmpState1[2]) } elsif ($n == 79) { ($tmpState1[4], $tmpState2[4]) = ($tmpState2[4], $tmpState1[4]) } } $state[0] = mod($state[0] + $tmpState1[0]); $state[1] = mod($state[1] + $tmpState1[1]); $state[2] = mod($state[2] + $tmpState1[2]); $state[3] = mod($state[3] + $tmpState1[3]); $state[4] = mod($state[4] + $tmpState1[4]); $state[5] = mod($state[5] + $tmpState2[0]); $state[6] = mod($state[6] + $tmpState2[1]); $state[7] = mod($state[7] + $tmpState2[2]); $state[8] = mod($state[8] + $tmpState2[3]); $state[9] = mod($state[9] + $tmpState2[4]); } sub rmdInit { $blockLen = 64; local ($bw) = shift; if ($bw == 128) { @state = ( 0x67452301 , 0xEFCDAB89 , 0x98BADCFE , 0x10325476 ); *round = *rmd128roundz; } elsif ($bw == 160) { @state = ( 0x67452301 , 0xEFCDAB89 , 0x98BADCFE , 0x10325476 , 0xC3D2E1F0 ); *round = *rmd160roundz; } elsif ($bw == 256) { @state = ( 0x67452301 , 0xEFCDAB89 , 0x98BADCFE , 0x10325476 , 0x76543210 , 0xFEDCBA98 , 0x89ABCDEF , 0x01234567 ); *round = *rmd256roundz; } elsif ($bw == 320) { @state = ( 0x67452301 , 0xEFCDAB89 , 0x98BADCFE , 0x10325476 , 0xC3D2E1F0 , 0x76543210 , 0xFEDCBA98 , 0x89ABCDEF , 0x01234567 , 0x3C2D1E0F ); *round = *rmd320roundz; } return if @s and @s2 and @r and @r2; @s = ( 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, ); @s2 = ( 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11, ); @r = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, ); @r2 = ( 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11, ); } &arg_check if @ARGV; sub arg_check { $switch = shift @ARGV; $switch_128 = "/128"; $switch_128f = "/128f"; $switch_256 = "/256"; $switch_256f = "/256f"; $switch_160 = "/160"; $switch_160f = "/160f"; $switch_320 = "/320"; $switch_320f = "/320f"; $maxLineLen = 40; $sltMsgTmpl = "%-6s : %s\n"; if ($switch =~ m{^/?(\?|help)$}i) { &arg_help; } elsif ($switch =~ m{^($switch_128|$switch_256|$switch_160|$switch_320)$}i) { if (!@ARGV) { arg_help( 'ハッシュ値を得たい文字列を入力してください' ); } ($bit_w) = $switch =~ /(\d+)/; foreach (@ARGV) { if (length($_) > $maxLineLen) { $tmp = substr $_, 0, $maxLineLen-5; $tmp .= "....."; } else { $tmp = $_; } printf $sltMsgTmpl, "String", $tmp; printf $sltMsgTmpl, "RIPEMD-$bit_w", $tmp = &{"rmd${bit_w}"}($_); printf "\n"; } } elsif ($switch =~ m{^($switch_128f|$switch_256f|$switch_160f|$switch_320f)$}i) { if (!@ARGV) { arg_help( 'ハッシュ値を得たいファイルを入力してください' ); } ($bit_w) = $switch =~ /(\d+)/; foreach (@ARGV) { printf $sltMsgTmpl, "File", $_; $tmp = &{"rmd${bit_w}f"}($_); if ($tmp eq "error") { printf $sltMsgTmpl, "Error", 'ファイルを開けません'; } else { printf $sltMsgTmpl, "RIPEMD-$bit_w", $tmp; } print "\n"; } } elsif ($switch =~ m|^(/.+)|) { arg_help( sprintf '"%s" というスイッチはありません', $1 ); } else { arg_help( '引数が変です' ); } } sub arg_help { if (@_) { printf "=========================================\n" . "* ERROR\n" . "%s\n" . "=========================================\n", shift; } print "Usage\n\n" . " .....\n\n" . "* switches\n\n"; printf " %-12s %-10s # %s\n", $switch_128, '"string"', '文字列のRIPEMD-128を計算'; printf " %-12s %-10s # %s\n", $switch_128f,'"file"', 'ファイルのRIPEMD-128を計算'; printf " %-12s %-10s # %s\n", $switch_160, '"string"', '文字列のRIPEMD-160を計算'; printf " %-12s %-10s # %s\n", $switch_160f,'"file"', 'ファイルのRIPEMD-160を計算'; printf " %-12s %-10s # %s\n", $switch_256, '"string"', '文字列のRIPEMD-256を計算'; printf " %-12s %-10s # %s\n", $switch_256f,'"file"', 'ファイルのRIPEMD-256を計算'; printf " %-12s %-10s # %s\n", $switch_320, '"string"', '文字列のRIPEMD-320を計算'; printf " %-12s %-10s # %s\n", $switch_320f,'"file"', 'ファイルのRIPEMD-320を計算'; printf " %-12s %-10s # %s\n", "/? or /help", "", '今読んでいるコレを表\示'; } 1;