Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Alpha-search, by letter.

by Andrew_Levenson (Hermit)
on Mar 14, 2006 at 21:14 UTC ( [id://536705]=perlquestion: print w/replies, xml ) Need Help??

Andrew_Levenson has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to write an "encryption" program, and i'm started by writing a very basic one so I can get the hang of it. My only problem is, I cannot figure out how to do a search and replace for the entire alphabet, but have it go letter by letter. Can anyone show me how to fix my code to do that? (Please do not show me fancy, advanced ways to make the code shorter though, I want the first run-through to be in a way I can read. I just need this issue resolved.)
use strict; use warnings; my $i; chomp(my $message=<>); $message=join(" ",(split(//, $message))); my $j=0; for $i([A-Z]){ $message=~s/$i/($j+6)/i; $j++; } my $g=6; for $i([A-Z]){ $message=~s/$g/$i/i; $g++; } print $message;
Thanks in advance.

Replies are listed 'Best First'.
Re: Alpha-search, by letter.
by japhy (Canon) on Mar 14, 2006 at 22:27 UTC
    No one's told you what's specifically wrong with the code you have. Not knowing what's wrong means you'll try the same things again later for a different program.

    First, for $i ([A-Z]) { ... } doesn't do what you think it does. This is not a regex; [A-Z] doesn't mean "A" through "Z". For that, you want for $i ('A' .. 'Z') { ... }.

    Second, s/$i/($j+6)/i doesn't execute the right-hand side as code unless you add the /e modifier: s/$i/$j+6/ie. And you'll want to add the /g modifier as well, to replace all occurrences of A with 6, B with 7, etc.

    Finally, your second substitution is broken. It will replace 6 with A, but it will also change 16 into 1A. You'll need \b (word boundary) in the regex to restrict the matching: s/\b$g\b/$i/g;. And the /i modifier is useless in this case.


    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Alpha-search, by letter.
by rafl (Friar) on Mar 14, 2006 at 21:20 UTC

    How about using tr/// ?

    $string =~ tr/n-za-m/a-z/;

    Cheers, Flo

      How does tr/// work, exactly? I can't find it in the perlops.
      Thanks.

        See

        tr/SEARCHLIST/REPLACEMENTLIST/cds
        y/SEARCHLIST/REPLACEMENTLIST/cds
        

        in perlop. It's around line 1100 in my version.

        Transliteration is what you're trying to do- map one set of characters onto another set. Specifically, you're trying to implement rot6, a transliteration cipher (not much of an encryption, btw).

        tr///, aka y///, uses the second set of characters to replace their counterparts from the first set.

        my $word = "abc"; $abc =~ tr/acb/llo/; print $word;
        yeilds: lol
        Use this link: tr///

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Re: Alpha-search, by letter.
by ikegami (Patriarch) on Mar 14, 2006 at 22:23 UTC

    Fixed up, your code would be

    use strict; use warnings; my $rot = 6; chomp(my $message = lc(<>)); $message =~ s/([a-z])/ chr( ( ord($1) - ord('a') + $rot + 26 ) % 26 + ord('a') ) /ge; print("$message\n");
    or
    use strict; use warnings; my $rot = 6; my $src = join '', 'a'..'z'; my $dst = substr($src, $rot) . substr($src, 0, $rot); chomp(my $message = lc(<>)); eval "\$message =~ tr/$src/$dst/;"; print("$message\n");
    or for repeated use
    use strict; use warnings; my $rot = 6; my $src = join '', 'a'..'z'; my $dst = substr($src, $rot) . substr($src, 0, $rot); my $tr = eval "sub { local \$_ = \@_ ? \$_[0] : \$_; tr/$src/$dst/; return \$_; }"; chomp(my $message = lc(<>)); $message = $tr->($message); print("$message\n");

    Set $rot to -6 to "decrypt".

    This method of encrpytion is particularly bad because

    • the frequency of the letters remains unchanged making the cypher easy to identify and the cyphertext easy to decrypt by observing the statistical distribution of the letters, and
    • the punctuation remains unencrypted, making the cyphertext easy to decrypt by observing the statistical length and organization of the words.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://536705]
Approved by ptum
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-24 17:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found