Thanks to all for replying, biggest mistake I made was not clearing the string but have been comparing how others would have done the same script and finding it very useful. Am not a great scripter so all hints welcome, will be checking scripts for techniques.
On Wed, 2004-03-10 at 09:09, John W. Krahn wrote: > Gordon Low wrote: > > > > Wondered if anyone can throw some light on why this script won't act > > properly. > > Certainly. > > > Wrote it to convert a string using a ceaser cipher for a course I am > > doing. Basically get the string and replace each character with the > > character offset by 3 or 4 up to 26. Have to try up to 26 times so it > > was crying out for a script, trouble is it doesn't work the way I > > intended and I cannot see how. > > > > No real attempts at error catching have been done as it was only > > supposed to be used by myself. > > Supposed to do this > > Enter > > >cipher.pl phhw dw plgqljkw > > ...and get all 26 different combinations to crack the message. > > Trouble is I get this..... > > qiix ex qmhrmklx -------> offset = 1 <------- > > qiix ex qmhrmklx -------> offset = 1 <------- > > rjjy fy rnisnlmy -------> offset = 2 <------- > > qiix ex qmhrmklx -------> offset = 1 <------- > > rjjy fy rnisnlmy -------> offset = 2 <------- > > skkz gz sojtomnz -------> offset = 3 <------- > > qiix ex qmhrmklx -------> offset = 1 <------- > > rjjy fy rnisnlmy -------> offset = 2 <------- > > skkz gz sojtomnz -------> offset = 3 <------- > > tlla ha tpkupnoa -------> offset = 4 <------- > > > > Instead of just going through once it is repeating ie loops to 1 then > > loops to 2 then loops to 3 up till loops to 25. Cracks the message ok at > > offset 23 but I don't want it looping all the time. Code follows, I am > > on Linux 8.0 with Perl 5.8, there is probably better ways to do this but > > it is driving me mad trying to see the logical problem, hoping someone > > can help. > > > > ******************************************************************* > > #!/usr/bin/perl -w > > use strict; > > > > my @alpha = > > ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); > > Ouch. Writing out each letter is error prone. It is better to use the > range operator to create the list. > > my @alpha = 'a' .. 'z'; > > > my %alphat; > > my $count; > > my $ceascount; > > my $op = ""; > > > > foreach (@alpha){ # set up a lookup table for the array > > offset > > $alphat{$alpha[$count]} = $count; > > $count++; > > } > > When this loop runs I get the warning: > > Use of uninitialized value in array element at ./cipher.pl line 92. > > Where line 92 is "$alphat{$alpha[$count]} = $count;" because the initial > value in $count is undef. You can explicitly set $count: > > my $count = 0; > foreach ( @alpha ){ # set up a lookup table for the array offset > $alphat{ $alpha[ $count ] } = $count; > $count++; > } > > However, I was wondering why you are looping through the values in @alpha > but not using them? > > foreach ( @alpha ){ # set up a lookup table for the array offset > $alphat{ $_ } = $count++; > } > > That eliminates the warnings message and makes the code shorter and easier > to read but you can do the same thing without the foreach loop and the $count > variable by using a hash slice: > > # set up a lookup table for the array offset > @alphat{ @alpha } = 0 .. $#alpha; > > > > for ($ceascount = 1; $ceascount < ($#alpha +1);$ceascount++,print > > $op){ # try all ceaser cipher offsets > > That looks more like C then Perl. :-) A more perl-ish way to write that is: > > for my $ceascount ( 1 .. $#alpha ) { # try all ceaser cipher offsets > ... > } > continue { > print $op; > } > > Your problem is that after printing $op it retains the contents from the > previous iteration of the loop. You need to clear out the contents of $op > after you print it: > > for my $ceascount ( 1 .. $#alpha ) { # try all ceaser cipher offsets > ... > } > continue { > print $op; > $op = ''; > } > > > > foreach (@ARGV){ # take in each command line arg > > for ($count=0; $count < length($_); $count++){ # go through > > each arg and convert with cipher > > A more perl-ish for loop would be: > > for my $count ( 0 .. length() - 1 ){ # go through each arg and convert > with cipher > > > > $op .= $alpha[($alphat{substr($_,$count,1)} + $ceascount) % > > ($#alpha+1)]; # conversion > > } > > $op .= " "; # space between args > > } > > $op .= " -------> offset = $ceascount <-------\n"; # final result > > } # use another ceaser cipher offset > > A simpler way to write that: > > #!/usr/bin/perl > use warnings; > use strict; > > my @alpha = 'a' .. 'z'; > my @ceaser = @alpha[ 1 .. $#alpha, 0 ]; > > my %alphat; > @alphat{ @alpha } = @ceaser; > > my $code = "@ARGV"; > > for my $ceascount ( 1 .. $#alpha ) { > ( my $message = $code ) =~ s/([EMAIL PROTECTED])/ exists $alphat{ $1 } ? > $alphat{ $1 } : $1 /eg; > print "$message -------> offset = $ceascount <-------\n"; > @alphat{ @alpha } = @ceaser = @ceaser[ 1 .. $#ceaser, 0 ]; > } > > __END__ > > > > John > -- > use Perl; > program > fulfillment > > -- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > <http://learn.perl.org/> <http://learn.perl.org/first-response> > > -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>