henzcoop has asked for the wisdom of the Perl Monks concerning the following question:
Okay, a newbie here. I'm trying to do a very simple little "secret code" script that prompts the user for a message, then substitutes the letters based on a randomly generated alphabet, made fresh each time. The problem comes when I try to drop the $string into the tr// operation. From searching around forums and looking at the manual, I think it has something to do with eval() being needed to interpolate the $string.
Greatly appreciate any perls of wisdom! Many thx.
Jamie
#!/usr/bin/perl
# transliterate.pl
use strict; use warnings;
print "Please enter your message to be encrypted.\n";
my $message = <STDIN>;
chomp($message);
# generate randomized alphabet
my @chars = ("A".."Z", "a".."z");
my $string;
$string .= $chars[rand @chars] for 1..26;
# I want to drop the random alphabet in $string into the replace-with
+slot of tr//
my $code = eval($message =~ tr/abcdefghijklmnopqrstuvwxyz/$string/);
print "Here is your encrypted message: $code\n";
# As is, $code returns the number of letters in the message.
Re: secret code, transliteration prob
by Athanasius (Archbishop) on Apr 12, 2016 at 14:13 UTC
|
Hello henzcoop,
You’re nearly there. But (1) eval returns the value of the last expression evaluated; but you don’t want the number of transliterations, you want the transliterated string, which is $message. (2) Within an eval, a variable such as $message will itself be interpolated. But you want to evaluate the expression $message =~ ..., so you need to escape the $ sigil to prevent interpolation of the $message variable into the string to be evaluated.
#! perl
use strict;
use warnings;
print "Please enter your message to be encrypted.\n";
my $message = <STDIN>;
chomp($message);
# generate randomized alphabet
my @chars = ("A".."Z", "a".."z");
my $string;
$string .= $chars[rand @chars] for 1..26;
# I want to drop the random alphabet in $string into the replace-with
+slot of tr//
eval "\$message =~ tr/a-z/$string/;";
print "Here is your encrypted message: $message\n";
Alternatively, you can add an /r modifier to the transliteration to get it to return the transliterated value:
my $code = eval "\$message =~ tr/a-z/$string/r;";
print "Here is your encrypted message: $code\n";
See the entry for tr/SEARCHLIST/REPLACEMENTLIST/cdsr under perlop#Quote-Like-Operators.
Hope that helps,
| [reply] [d/l] [select] |
|
| [reply] |
Re: secret code, transliteration prob
by BrowserUk (Patriarch) on Apr 12, 2016 at 14:17 UTC
|
tr/// modifies the string you apply it to rather than returns the modified value. And, you need string eval not block eval:
eval "\$message =~ tr/abcdefghijklmnopqrstuvwxyz/$string/);
Note that you must escape $message, but not $string. After the above code, $message will contain the "secret code".
(One thing: How are you going to decrypt it, given that the encryption key will be lost when the program ends?)
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
Good question, Browser. The de-encryption step will take some thought. For now, though, I can at least make my very own cryptograms. Thanks for the feedback!
| [reply] |
|
| [reply] |
|
Re: secret code, transliteration prob
by NetWallah (Canon) on Apr 12, 2016 at 17:43 UTC
|
You have an issue with the encoding : your $string will most likely contain repeated letters. i.e. letters occurring more than once.
This will cause problems when decoding, because multiple letters will be mapped to those repeated letters.
Here is (an inefficient, but functioning) way to avoid that when creating $string:
my $string = join '',map {splice(@chars,rand @chars,1)} 1..26;
This is not an optical illusion, it just looks like one.
| [reply] [d/l] |
Re: secret code, transliteration prob
by stevieb (Canon) on Apr 12, 2016 at 14:15 UTC
|
my $code;
eval "(\$code = \$message) =~ tr/abcdefghijklmnopqrstuvwxyz/$string/";
# in
steve
#out
fnbrb
| [reply] [d/l] [select] |
|
| [reply] |
|
|