Simple Encryption Script

N

Nikos

#!/usr/bin/perl

print "Enter text to be encrypted: ";
$toBeEncrypted = <>;

@letters = split //, $toBeEncrypted; # load the user input to an array
letter by letter

foreach (@letters) {
$letters[$_] = chr($letters[$_] + 1); # take each letter and convert it
to the next one alphabetically
}

print "Encrypted text now is: @letters\n";


I have made the ebove, but somehow aint working.
 
J

Josef Moellers

Nikos said:
#!/usr/bin/perl

print "Enter text to be encrypted: ";
$toBeEncrypted = <>;

@letters = split //, $toBeEncrypted; # load the user input to an array
letter by letter

foreach (@letters) {
$letters[$_] = chr($letters[$_] + 1); # take each letter and convert it
to the next one alphabetically
}

print "Encrypted text now is: @letters\n";


I have made the ebove, but somehow aint working.

$_ is an alias for the currently selected element of @letters. Also, if
$_ contains a letter, it contains a letter, not a number, so
incrementing won't work:

$_ = chr(ord($_) + 1);

If you've added "use warnings; use strict;", perl would've told you that

Enter text to be encrypted: Hello
Argument "H" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "e" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "^A" isn't numeric in addition (+) at enc.pl line 12, <> line 1.
Argument "l" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "^A" isn't numeric in addition (+) at enc.pl line 12, <> line 1.
Argument "l" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "^A" isn't numeric in addition (+) at enc.pl line 12, <> line 1.
Argument "o" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "^A" isn't numeric in addition (+) at enc.pl line 12, <> line 1.
Argument "\n" isn't numeric in array element at enc.pl line 12, <> line 1.
Argument "^A" isn't numeric in addition (+) at enc.pl line 12, <> line 1.
Encrypted text now is: e l l o

Note: You should watch out for wrap-arounds ("encrypting" the last
letter in the alphabet).

Josef
 
J

John W. Krahn

Nikos said:
#!/usr/bin/perl

use warnings;
use strict;
print "Enter text to be encrypted: ";
$toBeEncrypted = <>;

chomp( my $toBeEncrypted = said:
@letters = split //, $toBeEncrypted; # load the user input to an array
letter by letter

No need to convert the string to an array:

$toBeEncrypted =~ tr/a-zA-Z/b-zA-Za/;

print "Encrypted text now is: $toBeEncrypted\n";



John
 
A

Anno Siegel

John W. Krahn said:
use warnings;
use strict;




No need to convert the string to an array:

$toBeEncrypted =~ tr/a-zA-Z/b-zA-Za/;

print "Encrypted text now is: $toBeEncrypted\n";

Not quite. The OPs intended encryption scheme was "chr 1 + ord $c",
so "z" should map to "{" and "Z" to "[". Yours maps "z" to "A" and
"Z" to "a".

Anno
 
N

Nikos

$_ is an alias for the currently selected element of @letters. Also, if
$_ contains a letter, it contains a letter, not a number, so
incrementing won't work:

$_ = chr(ord($_) + 1);

thanks here it is now correct:

#!/usr/bin/perl -w

$i=0;

print "Enter text to be encrypted: ";
$text = <>;
chomp($text);

@letters = split //, $text;

foreach (@letters) {
$letters[$i++] = chr( ord($_) + 1 );
}

print "\nEncrypted text now is: @letters\n";


The only proble now is that i get the encryptes text in @letters but with
spaces between each letter ie if encryptes etxt is "idfjs" i get it as "i
d f j s". Why?

It must something in the split part but its the only way i know to get
each letter from a variable. do you know some better way to get the
letter in an array from $text?
 
N

Nikos

use warnings;
use strict;


chomp( my $toBeEncrypted = <> );

why this wotn work?

$toBeEncrypted = chomp ( said:
No need to convert the string to an array:

$toBeEncrypted =~ tr/a-zA-Z/b-zA-Za/;

a-z transletes to b-z
A-Z msut to B-Z why you say A-Za ?
 
J

John W. Krahn

Nikos said:
[email protected]:

$_ is an alias for the currently selected element of @letters. Also, if
$_ contains a letter, it contains a letter, not a number, so
incrementing won't work:

$_ = chr(ord($_) + 1);


thanks here it is now correct:

#!/usr/bin/perl -w

$i=0;

print "Enter text to be encrypted: ";
$text = <>;
chomp($text);

@letters = split //, $text;

foreach (@letters) {
$letters[$i++] = chr( ord($_) + 1 );
}

Could be written more simply as:

foreach ( @letters ) {
$_ = chr 1 + ord;
}

print "\nEncrypted text now is: @letters\n";


The only proble now is that i get the encryptes text in @letters but with
spaces between each letter ie if encryptes etxt is "idfjs" i get it as "i
d f j s". Why?

perldoc -q "Why do I get weird spaces when I print an array of lines"



John
 
J

John W. Krahn

Anno said:
John W. Krahn said:
use warnings;
use strict;



No need to convert the string to an array:

$toBeEncrypted =~ tr/a-zA-Z/b-zA-Za/;

print "Encrypted text now is: $toBeEncrypted\n";


Not quite. The OPs intended encryption scheme was "chr 1 + ord $c",
so "z" should map to "{" and "Z" to "[". Yours maps "z" to "A" and
"Z" to "a".

Then I guess that this should work:

$toBeEncrypted =~ tr/\0-\xff/\1-\xff\0/;


Or even:

$toBeEncrypted =~ s/(.)/ chr 1 + ord $1 /esg;



John
 
J

John W. Krahn

Nikos said:
why this wotn work?

$toBeEncrypted = chomp (<>);

Because chomp() returns the number of times that $/ was removed, not the string.

perldoc -f chomp

a-z transletes to b-z
A-Z msut to B-Z why you say A-Za ?

a-z translates to b-zA and A-Z to B-Za, or more explicitly:
abcdefghijklmnopqrstuvwxyz to bcdefghijklmnopqrstuvwxyzA and
ABCDEFGHIJKLMNOPQRSTUVWXYZ to BCDEFGHIJKLMNOPQRSTUVWXYZa



John
 
A

Anno Siegel

Nikos said:
$_ is an alias for the currently selected element of @letters. Also, if
$_ contains a letter, it contains a letter, not a number, so
incrementing won't work:

$_ = chr(ord($_) + 1);

thanks here it is now correct:

#!/usr/bin/perl -w

$i=0;

print "Enter text to be encrypted: ";
$text = <>;
chomp($text);

@letters = split //, $text;

foreach (@letters) {
$letters[$i++] = chr( ord($_) + 1 );
}

print "\nEncrypted text now is: @letters\n";

It works now, but it is still somewhat roundabout. You can change
the array elements one by one in the foreach loop, there is no need to
use an index ($i) to access them:

foreach ( @letters ) {
$_ = 1 + chr ord $_;
}
The only proble now is that i get the encryptes text in @letters but with
spaces between each letter ie if encryptes etxt is "idfjs" i get it as "i
d f j s". Why?

This (well, a closely related question) is answered in the FAQ. Use
perldoc -q 'spaces' to find it.
It must something in the split part but its the only way i know to get
each letter from a variable. do you know some better way to get the
letter in an array from $text?

It's not in the split(). You never bothered to join the string together
again, that's what's wrong. In Perl, an array of characters is *not*
the same as a string. You can do it like this:

my $encrypted = join '', map chr 1 + ord, split //, $text;

Alternatively, use a regular expression to access the characters
individually. Encryption happens through the /e modifier of s///
(explained in perlop):

( my $encrypted = $text) =~ s/(.)/chr 1 + ord $1/eg;

Anno
 
N

Nikos

Nikos said:
[email protected]:

$_ is an alias for the currently selected element of @letters. Also,
if $_ contains a letter, it contains a letter, not a number, so
incrementing won't work:

$_ = chr(ord($_) + 1);


thanks here it is now correct:

#!/usr/bin/perl -w

$i=0;

print "Enter text to be encrypted: ";
$text = <>;
chomp($text);

@letters = split //, $text;

foreach (@letters) {
$letters[$i++] = chr( ord($_) + 1 );
}

Could be written more simply as:

foreach ( @letters ) {
$_ = chr 1 + ord;
}

Thank you but i cant understand how your example works.

whats chr 1 and ord by itslef gives?
perldoc -q "Why do I get weird spaces when I print an array of lines"

Yes i saw that another thing is

print @letters ; #Gives the elements joined together.
and another is
print "@letters; # Gives the elements joined together but with a
space bettwen them.

Until now i thoughs that if we ommited the doubles quotes in a print it
would be tha same as haveing it, meaning that the $variable or @array
would still be interpolated.

But why is that difference?
 
N

Nikos

(e-mail address removed)-berlin.de (Anno Siegel) wrote in @mamenchi.zrz.TU-Berlin.DE:
foreach ( @letters ) {
$_ = 1 + chr ord $_;
}

Yes but this wont change the value of its element. i mean the new value of
every element will not be stored it will just change.
 
C

Chris Mattern

Nikos said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in @mamenchi.zrz.TU-Berlin.DE:


Yes but this wont change the value of its element. i mean the new value of
every element will not be stored it will just change.
You might want to actually, y'know, try it before you state it doesn't
work. Or you could read the documentation for foreach.

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
J

John W. Krahn

Nikos said:
Nikos said:
[email protected]:

@letters = split //, $text;

foreach (@letters) {
$letters[$i++] = chr( ord($_) + 1 );
}

Could be written more simply as:

foreach ( @letters ) {
$_ = chr 1 + ord;
}

Thank you but i cant understand how your example works.

whats chr 1 and ord by itslef gives?

In a foreach loop the $_ variable is an alias to the elements of the array
@letters so modifying $_ actually modifies the contents of @letters.

The chr operator is passed the expression "1 + ord" and ord by default is
passed the contents of $_.

Yes i saw that another thing is

print @letters ; #Gives the elements joined together.
and another is
print "@letters; # Gives the elements joined together but with a
space bettwen them.

Until now i thoughs that if we ommited the doubles quotes in a print it
would be tha same as haveing it, meaning that the $variable or @array
would still be interpolated.

But why is that difference?

Because double quoted strings are affected by the contents of the $" variable
just as the print operator is affected by the contents of the $, and $\
variables (and sometimes even the $_ and $| variables.)

perldoc perlvar


John
 
J

John W. Krahn

Anno said:
It works now, but it is still somewhat roundabout. You can change
the array elements one by one in the foreach loop, there is no need to
use an index ($i) to access them:

foreach ( @letters ) {
$_ = 1 + chr ord $_;
}

You are adding one to the character returned from chr()?

$ perl -le'
@x = qw/ a b c 1 2 3 9 h x y z /;
for ( @x ) { $_ = 1 + chr ord }
print "@x"
'
1 1 1 2 3 4 10 1 1 1 1



John
 
T

Tad McClellan

Nikos said:
Thank you but i cant understand how your example works.


Did you read the docs for the parts that you don't understand?

whats chr 1


The documentation for chr() says what the chr() function does:

perldoc -f chr

and ord by itslef gives?


The documentation for ord() says what the ord() function does:

perldoc -f ord

Until now i thoughs that if we ommited the doubles quotes in a print it
would be tha same as haveing it, meaning that the $variable or @array
would still be interpolated.

But why is that difference?


Because that is how it is documented to be in Perl.
 
N

Nikos

In a foreach loop the $_ variable is an alias to the elements of the
array @letters so modifying $_ actually modifies the contents of
@letters.

ah, i see. I thought so far that $_ just copied itself the current
element of array @letters but it was just a copy, meaning that if any
change were applied to $_ it wouldnt impact at all each of the elements.

for ie in the first iteration

$_ == $letters[0]

If a change happened to $_ it wooulsnt change the real elements value.


foreach ( @letters ) <-- this can also be writen as

foreach $_( $letters )

foreach ( $letters[0]..$letters[@letters] )

right?
The chr operator is passed the expression "1 + ord" and ord by default
is passed the contents of $_.

i see, thank you.
 
N

Nikos

@letters = split //, $text;

Iam also using this but i cant quite understab how it works:

i mean how split manages to split $text's each letter? what // really does?
letters in $text dont really have a space between them so split can use to
seperate one from the other. so how can it really manages it?
 
A

A. Sinan Unur

ah, i see. I thought so far that $_ just copied itself the current
element of array @letters but it was just a copy, meaning that if any
change were applied to $_ it wouldnt impact at all each of the
elements.

From perldoc perlsyn

Foreach Loops
....
If any element of LIST is an lvalue, you can modify it by modifying VAR
inside the loop. Conversely, if any element of LIST is NOT an lvalue,
any attempt to modify that element will fail. In other words, the
"foreach" loop index variable is an implicit alias for each item in the
list that you're looping over.
foreach ( @letters ) <-- this can also be writen as

foreach $_( $letters )

foreach ( $letters[0]..$letters[@letters] )

right?

Wrong.

use strict;
use warnings;

my @x = 1, 2, 3;

for ($x[0] .. $x[@x]) {
print "$_\n";
}

__END__

D:\Home> f
Use of uninitialized value in foreach loop entry at D:\Home\f.pl line 6.

Guess why.

Sinan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top