SM177Y has asked for the wisdom of the Perl Monks concerning the following question:
<SOLVED!! (not the index lookup but the actual problem from my original example). Reversal is possible with almost no time difference.> I also was looking for a method to do this, preferably the fastest possible. With a relatively small array (256), the use List::Util qw(first); method was actually significantly slower than simply iterating through the array and breaking(last) out once the match was found. In my test example on a 2.5MB (2560000bytes) file doing a sort of Sbox type lookup, the iterating took about 3m45s on my old Atom netbook where as the use List::Util qw(first); method required over 5m. Does anyone know the fastest way to perform these index lookups? A few of the examples shown appear to be basically identical. Hashing an array(did I say that right?) is a concept I am not yet familiar with.
I just tried the index hashing method described in the original post I found info on this as well and on the same file went at a grueling pace...Around 15mins. Is there really no other way to perform this operation faster than simply iterating through the array?
Looks like I solved the timing issue in my posted code by re-ordering the array by it's own values. Fixed code shown below.
#!/usr/bin/env perl use strict; #use warnings; my $key="a5e0d57354e5fb898a44a979582536141ca3819d1c457db21e3cdf64bdc90 +01d1903ea7d9814649b2e6edee9674d57a5e47a3b0fcb5dbc8de3181c617c88650a88 +f9ff4a9852538087dabf35a596d657c86715d89701edefee55453302488ec3aae6a53 +20319a13ffbd11eb31a7e5c921421a4728b86523889fa20a44f19c4d4abf302490e39 +b5fa50619a18acf9785b6f1bd55158e1405776fb0ee2f3fa5f56aa828b8c22bd6f4e6 +70c23edefb08add86cc5d3415aaa64a4fcf677d2198f1801d800c6762a84e7b0e1053 +b95c38c94fdd637757c2f0ef5d0c628ddf1e83e4f178a00cefd41f58c3b4c2fa71c5e +d56bfa6aa321120978fbe6f8dfa7fc2b5f109"; $key=pack('H*',$key); my @sbase; for my $i (0..255){$sbase[$i]=chr($i)}; my @sbox=sbox_gen(@sbase); if ( $ARGV[2] eq "fwd" ) { swap(@sbox); } elsif ( $ARGV[2] eq "rev" ) { @sbox=sbox_reindex(@sbox); swap(@sbox); } sub swap { my ($n,$infile,$buf,$data,$outfile,$tmp); my @sbox=@_; open($infile,"<",$ARGV[0]) or die $!; binmode($infile); open($outfile,">",$ARGV[1]) or die $!; binmode($outfile); while (($n=sysread $infile,$buf,256)!=0){ for my $i (0..255) { $tmp=ord(substr($buf,$i,1)); $data.=$sbox[$tmp]; } print $outfile $data;$data=""; } close($outfile); close($infile); } sub sbox_gen { my @sbox; my @sary=@_; for my $i (0..255) { my $tmp=ord(substr($key,$i,1))**3; $tmp=$tmp%scalar(@sary); push @sbox,$sary[$tmp]; splice(@sary,$tmp,1); } return @sbox; } sub sbox_reindex { my @sbox=@_; my @out; for my $i (0..255) { my $a=ord($sbox[$i]); $out[$a]=chr($i); } return @out; }
Timings now:
$ time ./sbox.pl testfile outfile fwd real 0m3.424s user 0m3.330s sys 0m0.073s
$ time ./sbox.pl outfile revfile rev real 0m3.529s user 0m3.413s sys 0m0.083s
$ diff testfile revfile
$
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: How do I find the index of a specific array value?
by choroba (Cardinal) on Sep 15, 2015 at 09:43 UTC | |
by SM177Y (Initiate) on Sep 15, 2015 at 10:01 UTC |