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>


Reply via email to