package crypt; use strict; my $seed; sub makeSeq { my($range,$cnt)=@_; my @res; my $r; while (@res<$cnt) { $seed =( $seed * 23 +1 )% 65536; $r =$seed/(65536/$range); if ($r<$range) { push @res,$r; } } @res; } sub revCrypt { my($s,$rev)=@_; my @st = unpack("c*",$s); my($t,$i); my(@sa,@sb); $seed=0; foreach $t(@st){ $seed+=(($t-32) % 96); } @sa=&makeSeq($#st+1,($#st+1)*5); @sb=&makeSeq($#st+1,($#st+1)*5); if ($rev) { @sa=reverse @sa; @sb=reverse @sb; } for ($i=0 ; $i<=$#sa ; $i++) { if ($sa[$i]!=$sb[$i]) { $st[$sa[$i]]++;$st[$sa[$i]]-=96 if ($st[$sa[$i]]>=128); $st[$sb[$i]]--;$st[$sb[$i]]+=96 if ($st[$sb[$i]]<32); $t=$st[$sa[$i]]; $st[$sa[$i]]=$st[$sb[$i]]; $st[$sb[$i]]=$t; } } pack("c*",@st); } sub crypt { my($s)=@_; my($t)=7; my($seed)=48828125; my($r,$i,$j); my($res)=""; for ($j=0 ; $j<8 ; $j++) { $r=0; my @st = unpack("c*",$s); for ($i=0 ; $i<@st ; $i++){ $t=&mul($t,$seed); $r+=&mul(&mul($st[$i],$t),$seed); $r=&neg($r); } $res.=&hex($r); } return $res; } sub hex{ my $v=shift; #print "$v \n ..."; if ($v>=2**32) {printf "$v too big\n";} if ($v>=0) {sprintf("%x",$v);} else {sprintf("%x",2**32+$v);} } my $t16=65536; sub mul { my($a,$b)=@_; my($res); if ($a>=0 && $b>=0) { return &neg(&mulp($a,$b)); } if ($a>=0 && $b<=0) { $res=&mulp($a,-$b); $res = ((~$res)+1) & (2**32-1); return &neg($res); } if ($a<=0 && $b>=0) { $res=&mulp(-$a,$b); $res = ((~$res)+1) & (2**32-1); return &neg($res); } if ($a<=0 && $b<=0) { return &neg(&mulp(-$a,-$b)); } } sub neg { my($v)=@_; my $res; if ($v>=2**31) { $res=$v-2**32; if ($res>=2**32) { print "ERR $v \n"; } return $res; } if ($v<-(2**31)) { $res=$v+2**32; if ($res>=2**32) { print "ERR $v \n"; } return $res; } return $v; } sub mulp { my($a,$b)=@_; my($la)=$a % $t16; my($ha)=int($a / $t16); my($lb)=$b % $t16; my($hb)=int($b / $t16); my($l)=(($la*$lb) % $t16); my($n)=int(($la*$lb) / $t16); my($h)=$ha*$lb+$la*$hb+$n; $h=$h & 65535; my $res=$h*65536+$l; $res; }