CaesarCode1.mws

Caesar Codes

©Mike May, S. J., 2001

(Worksheet 1 for Cryptography)

>    restart:

Preliminaries

We start by preparing a standard message that we will use for our work.

>    message1 :="AZaz Good morning Mr. Phelps.  Your mission for today,
should you choose to accept it, is to encode this message. AZaz";

message1 :=
message1 :=

Note that a carriage return is recorded as \n.

The first method of encryption that we will look at is the Caesar Code.  Caesar encoded his messages by shifting each letter by three.  In the book that is done by converting the letters to numbers from 0 to 25 (ignoring upper and lower case), adding 3 (with remainders, so 27 converts to 2), then converting back to letters.    

We would like to mechanize the conversion from letters to numbers.  The easiest way to do this is with the convert command from Maple using the bytes option.

>    temp[1] := convert(message1, bytes);

temp[1] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[1] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[1] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[1] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...

The same command will convert the list of numbers back to a string.

>    temp[2] := convert(temp[1], bytes);

temp[2] :=
temp[2] :=

Note that the convert command does not convert letters to numbers between 0 and 25.  Instead it converts ASCII characters to numbers between 1 and 255 inclusive.  Since we want to recover encoded messages exactly, we will use this conversion.

>   

A first attempt at the Caesar cipher

We begin with a naive attempt at the Caesar cipher, shifting every letter by three.  

(We use the "map" command in Maple to apply a function to every element of a list.)

>    temp[2] := map(x->x+3,temp[1]);
convert(temp[2],bytes);

temp[2] := [68, 93, 100, 125, 35, 74, 114, 114, 103, 35, 112, 114, 117, 113, 108, 113, 106, 35, 80, 117, 49, 35, 83, 107, 104, 111, 115, 118, 49, 35, 35, 92, 114, 120, 117, 35, 112, 108, 118, 118, 108,...
temp[2] := [68, 93, 100, 125, 35, 74, 114, 114, 103, 35, 112, 114, 117, 113, 108, 113, 106, 35, 80, 117, 49, 35, 83, 107, 104, 111, 115, 118, 49, 35, 35, 92, 114, 120, 117, 35, 112, 108, 118, 118, 108,...
temp[2] := [68, 93, 100, 125, 35, 74, 114, 114, 103, 35, 112, 114, 117, 113, 108, 113, 106, 35, 80, 117, 49, 35, 83, 107, 104, 111, 115, 118, 49, 35, 35, 92, 114, 120, 117, 35, 112, 108, 118, 118, 108,...
temp[2] := [68, 93, 100, 125, 35, 74, 114, 114, 103, 35, 112, 114, 117, 113, 108, 113, 106, 35, 80, 117, 49, 35, 83, 107, 104, 111, 115, 118, 49, 35, 35, 92, 114, 120, 117, 35, 112, 108, 118, 118, 108,...

This did not give us quite the desired effect.  To begin with, we got rid of all the spaces and now have a single long word.  Furthermore, the letter z did not wrap around to c.  It was mapped to a special character.  The reason is that we have changed the alphabet.  When we switched to ASCII we put the 26 letters of the English alphabet into a 255 character alphabet that includes all the characters we would ever want to type into a computer.  In particular, spaces and special characters, as well as both upper and lower case letters are now part of our alphabet.

>    convert([1,2,3,4,64,65,66,97,98,121,122,123,127,128,97,129,130,256,97,98,99],bytes);
convert([97,255,128,97,132,97,164,97,200,97,255,97,255,97,97,254,97,98],bytes);
convert([65,255, 66, 256, 67, 257, 68], bytes);
convert([65,2,66, 1, 67, 0, 68, -2, 69],bytes);

Note that the convert function from integer to ASCII assumes the input is between 1 and   255, inclusive.  If fed an integer outside that range, it stops.  In that case, it does not process the rest of the list.

We want to look at conversion functions that use a standard alphabet as well as ones that use the ASCII alphabet.

The  first procedure we define uses the ASCII alphabet.  This procedure  shifts the value letter by the value key.  Notice that we have to take care that we get the correct results if letter + key is 254, 255, and 256.  (Check that the procedure outlined does take those values to 254, 255, and 1 respectively.)

>    caesara := proc(letter, key)
      ((letter + key - 1) mod 255) + 1;
      end:

Of course, the test of a coding procedure is that it encodes and decodes properly.

>    convert(temp[1], bytes);
temp[4] := map(caesara,temp[1],120);
code[1] := convert(temp[4],bytes);


temp[4] := [185, 210, 217, 242, 152, 191, 231, 231, 220, 152, 229, 231, 234, 230, 225, 230, 223, 152, 197, 234, 166, 152, 200, 224, 221, 228, 232, 235, 166, 152, 152, 209, 231, 237, 234, 152, 229, 225,...
temp[4] := [185, 210, 217, 242, 152, 191, 231, 231, 220, 152, 229, 231, 234, 230, 225, 230, 223, 152, 197, 234, 166, 152, 200, 224, 221, 228, 232, 235, 166, 152, 152, 209, 231, 237, 234, 152, 229, 225,...
temp[4] := [185, 210, 217, 242, 152, 191, 231, 231, 220, 152, 229, 231, 234, 230, 225, 230, 223, 152, 197, 234, 166, 152, 200, 224, 221, 228, 232, 235, 166, 152, 152, 209, 231, 237, 234, 152, 229, 225,...
temp[4] := [185, 210, 217, 242, 152, 191, 231, 231, 220, 152, 229, 231, 234, 230, 225, 230, 223, 152, 197, 234, 166, 152, 200, 224, 221, 228, 232, 235, 166, 152, 152, 209, 231, 237, 234, 152, 229, 225,...
temp[4] := [185, 210, 217, 242, 152, 191, 231, 231, 220, 152, 229, 231, 234, 230, 225, 230, 223, 152, 197, 234, 166, 152, 200, 224, 221, 228, 232, 235, 166, 152, 152, 209, 231, 237, 234, 152, 229, 225,...

code[1] :=

>    temp[5] := map(caesara,temp[4], -120);
convert(temp[5], bytes);

temp[5] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[5] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[5] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[5] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...


Exercises:

1)  Save the first full paragraph of page 1 of your book as message2.  Shift the message by 13 characters.  Convert your answer back by shifting -13 characters.  Verify that you get the original message back.

>   

2) Convert the message to numbers and shift the message by 120 characters, convert to ASCII, then back to numbers, shift the message by -120, then convert back to ASCII.  How has the message been changed?

>   

Caesar B - leaving special characters alone

A problem with using the full ASCII alphabet is that we shift to so many special characters that we would have trouble typing the encoded message.  For these reason we also want a coding procedure that rotates the letters but leaves the special characters alone.  Recall that the upper case letters are characters 65 through 90, while the lower case letters are ASCII characters 97 through 122.

>    caesarb := proc(letter, key)
   local temp, temp2;
   temp := letter:
 if temp > 64 then
   if temp < 91 then
      temp := 65 + ((temp - 65 + key) mod 26):
   fi:fi:
if temp > 96 then
   if temp < 123 then
      temp := 97 + ((temp - 97 + key) mod 26):
   fi:fi:
temp:
end:

Once again, the test is to encode messages.

>    convert(temp[1], bytes);
temp[6] := map(caesarb, temp[1], 3);
convert(temp[6], bytes);


temp[6] := [68, 67, 100, 99, 32, 74, 114, 114, 103, 32, 112, 114, 117, 113, 108, 113, 106, 32, 80, 117, 46, 32, 83, 107, 104, 111, 115, 118, 46, 32, 32, 66, 114, 120, 117, 32, 112, 108, 118, 118, 108, ...
temp[6] := [68, 67, 100, 99, 32, 74, 114, 114, 103, 32, 112, 114, 117, 113, 108, 113, 106, 32, 80, 117, 46, 32, 83, 107, 104, 111, 115, 118, 46, 32, 32, 66, 114, 120, 117, 32, 112, 108, 118, 118, 108, ...
temp[6] := [68, 67, 100, 99, 32, 74, 114, 114, 103, 32, 112, 114, 117, 113, 108, 113, 106, 32, 80, 117, 46, 32, 83, 107, 104, 111, 115, 118, 46, 32, 32, 66, 114, 120, 117, 32, 112, 108, 118, 118, 108, ...
temp[6] := [68, 67, 100, 99, 32, 74, 114, 114, 103, 32, 112, 114, 117, 113, 108, 113, 106, 32, 80, 117, 46, 32, 83, 107, 104, 111, 115, 118, 46, 32, 32, 66, 114, 120, 117, 32, 112, 108, 118, 118, 108, ...


>    temp[7] := map(caesarb, temp[6], -3);
convert(temp[7], bytes);
temp[8] := map(caesarb, temp[6], 23);
convert(temp[8], bytes);

temp[7] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[7] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[7] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[7] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...


temp[8] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[8] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[8] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...
temp[8] := [65, 90, 97, 122, 32, 71, 111, 111, 100, 32, 109, 111, 114, 110, 105, 110, 103, 32, 77, 114, 46, 32, 80, 104, 101, 108, 112, 115, 46, 32, 32, 89, 111, 117, 114, 32, 109, 105, 115, 115, 105, ...


Notice that if we shifted by 3 to encode, we can decode by using a shift of either -3 or +23.

We would like to put the procedures above into a simple encoding command

>    encodecaesarb := proc(message, key)
  local temp:
#first convert the message to numerical equivalents
  temp[1] := convert(message, bytes):
#then add the key to each letter to scrable the letters
  temp[2] := map(caesarb, temp[1], key):
#then convert back to the ASCII code
 convert(temp[2], bytes);
  end:

We will use this procedure on our standard message.

>    message1;
mess[2] := encodecaesarb(message1,3);


mess[2] :=
mess[2] :=

Exercise:

3) Use the modified procedure to shift message2, which you defined in exercise 1, by 3, 13, and 15 characters.

>   

Breaking Caesar

We conclude this section by producing a brute force code breaker for the Caesar code.  We simply take the message and do all possible shifts.  This is best done with a loop.

>    breakcaesarb := proc(message)
     local temp, key;
   for key from 1 to 25 do
      temp := encodecaesarb(message, - key):
      print(`The key of `||key,` produces - `,temp);
      od;
   end:

>    breakcaesarb(mess[2]);

`The key of 1`, ` produces - `,
`The key of 1`, ` produces - `,

`The key of 2`, ` produces - `,
`The key of 2`, ` produces - `,

`The key of 3`, ` produces - `,
`The key of 3`, ` produces - `,

`The key of 4`, ` produces - `,
`The key of 4`, ` produces - `,

`The key of 5`, ` produces - `,
`The key of 5`, ` produces - `,

`The key of 6`, ` produces - `,
`The key of 6`, ` produces - `,

`The key of 7`, ` produces - `,
`The key of 7`, ` produces - `,

`The key of 8`, ` produces - `,
`The key of 8`, ` produces - `,

`The key of 9`, ` produces - `,
`The key of 9`, ` produces - `,

`The key of 10`, ` produces - `,
`The key of 10`, ` produces - `,

`The key of 11`, ` produces - `,
`The key of 11`, ` produces - `,

`The key of 12`, ` produces - `,
`The key of 12`, ` produces - `,

`The key of 13`, ` produces - `,
`The key of 13`, ` produces - `,

`The key of 14`, ` produces - `,
`The key of 14`, ` produces - `,

`The key of 15`, ` produces - `,
`The key of 15`, ` produces - `,

`The key of 16`, ` produces - `,
`The key of 16`, ` produces - `,

`The key of 17`, ` produces - `,
`The key of 17`, ` produces - `,

`The key of 18`, ` produces - `,
`The key of 18`, ` produces - `,

`The key of 19`, ` produces - `,
`The key of 19`, ` produces - `,

`The key of 20`, ` produces - `,
`The key of 20`, ` produces - `,

`The key of 21`, ` produces - `,
`The key of 21`, ` produces - `,

`The key of 22`, ` produces - `,
`The key of 22`, ` produces - `,

`The key of 23`, ` produces - `,
`The key of 23`, ` produces - `,

`The key of 24`, ` produces - `,
`The key of 24`, ` produces - `,

`The key of 25`, ` produces - `,
`The key of 25`, ` produces - `,

It is clear that 3  is the key to unlocking the message.

Exercise:

4)  Decode the message `Vogsc Mkbbyv ckic "Dgkc lbsvvsq kxn dro cvsfoi dyfo."  Mkx iye snoxdspi dro gybu?` and answer the question.  Identify the key used to encode it.

>   

>   

>