Caesar Cipher
Caesar Cipher belongs to a class of Substitution Ciphers in which each letter in the plaintext is shifted a fixed number of places after it in the alphabet.
[edit] Example
In the classic example of shifting each letter by 3, plaintext TREATY IMPOSSIBLE would be encoded as wuhdwb lpsrvvleoh
[edit] Cryptanalysis
In the cases where space is preserved in the ciphertext, we could break down the message into separate words in order to determine the smallest words in the message. From there we could try to match up small words with one of the few common short words like am, is, to, be, he, we, and, are, you, she, .... Once the small words fall into place, you can try substituting for matching characters at other places in the ciphertext.
We can also analyze the frequency with which individual letters appear and compare them with statistical frequencies of those letters in the language. By noting the most frequently occurring letter in the cipher text we can easily deduce the shift parameter used in the cipher.
Since Caesar Cipher in this particular case is limited to English alphabet, brute force approach of listing all 26 possibilities is also feasible.
[edit] Code
Implementation of Caesar Cipher cryptanalysis tool:
#!/usr/bin/perl
# This quicky should display the use of Caesar Cipher
# as well as common approaches to breaking it.
#
# Note: For brevity, I am not doing a lot of the
# input sanity checks, so this code will break if not
# used properly
use strict;
if(@ARGV) {
# Encode the message given the shift value
if($ARGV[0] eq "-e" && $ARGV[2]) {
print "Ciphertext:\n";
foreach (split(//,uc($ARGV[1]))) {
print chr(65+(ord($_)-65+$ARGV[2])%26);
}
print "\n";
}
# Decode the message
elsif($ARGV[0] eq "-d") {
print "Plaintext:\n";
foreach (split(//,uc($ARGV[1]))) {
print lc(chr(65+(ord($_)-65-$ARGV[2])%26));
}
print "\n";
}
# For larger strings apply statistical analysis
elsif($ARGV[0] eq "-d1") {
print "Trying to count letter frequencies...";
my %freq;
my ($max_letter, $max_frequency);
foreach (split(//,uc($ARGV[1]))) {
$freq{$_} = $freq{$_} + 1;
if($freq{$_} > $max_frequency) {
$max_letter = $_;
$max_frequency = $freq{$_};
}
}
# Compare with the most frequent letter E
my $shift = ord($max_letter)-ord('E');
print "guessing a shift of $shift\n";
print "Plaintext:\n";
foreach (split(//,uc($ARGV[1]))) {
print lc(chr(65+(ord($_)-65-$shift)%26));
}
print "\n";
}
# Brute force shorter strings
else {
print "Brute Forcing...\n";
for my $shift (1..26) {
print "[$shift] ";
foreach (split(//,uc($ARGV[1]))) {
print lc(chr(65+(ord($_)-65-$shift)%26));
}
print "\n";
}
}
} else {
print "Caesar Cipher Encoder/Decoder\n";
print "=============================\n";
print "Usage:\n";
print " -e encode_message shift\n";
print " no spaces are allowed in plaintext message.\n";
print " -d decode_message shift\n";
print " -d1 decode_message\n";
print " try simple frequency analysis to determine the shift\n";
print " -d2 decode_message\n";
print " brute force method relying on users to find plaintext\n";
}
