Friday, May 11, 2012

A Caesar Cipher in Perl

While the Caesar Cipher is an extremely poor choice from a modern security standpoint, I find that it often makes a useful tool for introducing people to the concept of encryption.  Below is a simple set of Perl scripts that provide Caesar Cipher encryption and decryption functionalities.  Please note that these scripts were written with simplicity in mind to provide a more straightforward teaching tool and are thus lacking in error handling and validation checks.  As a result, feeding the scripts improper inputs or parameters may result in breakage of the script’s logic. 

To start let’s consider the following clear text excerpt taken from the book Dracula and saved in the file Dracula.txt. 

I had no answer for this, so was silent.  Van Helsing did not seem to
notice my silence.  At any rate, he showed neither chagrin nor
triumph.  He was looking intently at the face of the dead woman,
raising the eyelids and looking at the eyes, and once more opening the
lips and examining the teeth.  Then he turned to me and said,

"Here, there is one thing which is different from all recorded.  Here
is some dual life that is not as the common.  She was bitten by the
vampire when she was in a trance, sleep-walking, oh, you start.  You
do not know that, friend John, but you shall know it later, and in
trance could he best come to take more blood.  In trance she dies, and
in trance she is UnDead, too.  So it is that she differ from all
other.  Usually when the UnDead sleep at home," as he spoke he made a
comprehensive sweep of his arm to designate what to a vampire was
'home', "their face show what they are, but this so sweet that was
when she not UnDead she go back to the nothings of the common dead.
There is no malign there, see, and so it make hard that I must kill
her in her sleep."

Now let’s consider the Caesar Cipher which involves shifting each letter of the alphabet a fixed number of places.  For this sample case, we will use a shift of 7 places and our alphabet will comprise the “visible” set of ASCII characters.  We can implement the Caesar Cipher encryption as follows:

#!usr/bin/perl

# Copyright 2011- Christopher M. Frenz
# This script is free software it may be used, copied, redistributed, and/or modified
# under the terms laid forth in the Perl Artistic License

open(INPUT, "<Dracula.txt");
open(OUTPUT, ">DraculaEncrypted.txt");

$shift=7;

while(<INPUT>){
$text=$_;
$text =~ s/\r?\n$//;
@characters=split(//, $text);
$string="";

foreach $character(@characters){
   $asciinum=ord($character);
   if(($asciinum+$shift)<=126){
      $string=$string . chr($asciinum+$shift);
   }
   else{$string=$string . chr($asciinum+$shift-126+31)};
}

print OUTPUT "$string\n";
}

close INPUT;
close OUTPUT;

Running the passage through the above routine results in the following output:

P'ohk'uv'huz~ly'mvy'{opz3'zv'~hz'zpslu{5'']hu'Olszpun'kpk'uv{'zllt'{v
uv{pjl't!'zpslujl5''H{'hu!'yh{l3'ol'zov~lk'ulp{oly'johnypu'uvy
{yp|two5''Ol'~hz'svvrpun'pu{lu{s!'h{'{ol'mhjl'vm'{ol'klhk'~vthu3
yhpzpun'{ol'l!lspkz'huk'svvrpun'h{'{ol'l!lz3'huk'vujl'tvyl'vwlupun'{ol
spwz'huk'l htpupun'{ol'{ll{o5''[olu'ol'{|yulk'{v'tl'huk'zhpk3

)Olyl3'{olyl'pz'vul'{opun'~opjo'pz'kpmmlylu{'myvt'hss'yljvyklk5''Olyl
pz'zvtl'k|hs'spml'{oh{'pz'uv{'hz'{ol'jvttvu5''Zol'~hz'ip{{lu'i!'{ol
}htwpyl'~olu'zol'~hz'pu'h'{yhujl3'zsllw4~hsrpun3'vo3'!v|'z{hy{5''`v|
kv'uv{'ruv~'{oh{3'mypluk'Qvou3'i|{'!v|'zohss'ruv~'p{'sh{ly3'huk'pu
{yhujl'jv|sk'ol'ilz{'jvtl'{v'{hrl'tvyl'isvvk5''Pu'{yhujl'zol'kplz3'huk
pu'{yhujl'zol'pz'\uKlhk3'{vv5''Zv'p{'pz'{oh{'zol'kpmmly'myvt'hss
v{oly5''\z|hss!'~olu'{ol'\uKlhk'zsllw'h{'ovtl3)'hz'ol'zwvrl'ol'thkl'h
jvtwyloluzp}l'z~llw'vm'opz'hyt'{v'klzpnuh{l'~oh{'{v'h'}htwpyl'~hz
.ovtl.3'){olpy'mhjl'zov~'~oh{'{ol!'hyl3'i|{'{opz'zv'z~ll{'{oh{'~hz
~olu'zol'uv{'\uKlhk'zol'nv'ihjr'{v'{ol'uv{opunz'vm'{ol'jvttvu'klhk5
[olyl'pz'uv'thspnu'{olyl3'zll3'huk'zv'p{'thrl'ohyk'{oh{'P't|z{'rpss
oly'pu'oly'zsllw5)

Now that we have an encrypted form of the text, let’s reverse the process with the following decryption routine:

#!usr/bin/perl

# Copyright 2011- Christopher M. Frenz
# This script is free software it may be used, copied, redistributed, and/or modified
# under the terms laid forth in the Perl Artisic License

open(INPUT, "<DraculaEncrypted.txt");
open(OUTPUT, ">DraculaDecrypted.txt");

$shift=7;

while(<INPUT>){
$text=$_;
$text =~ s/\r?\n$//;
@characters=split(//, $text);
$string="";

foreach $character(@characters){
   $asciinum=ord($character);
   if(($asciinum-$shift)>=32){
      $string=$string . chr($asciinum-$shift);
   }
   else{$string=$string . chr($asciinum-$shift-32+127)}
}

print OUTPUT "$string\n";
}

close INPUT;
close OUTPUT;

Running the cipher text through the above decryption routine should return the original text. 

No comments: