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>