next up previous
Next: Improved Caesar-like ciphers Up: fsqFsHn sGGousG Previous: Defining functions with proc;

Caesar cipher redux

Now that we know about proc, let's implement the Caesar cipher again, this time with an alphabet of our choosing.

First, we define a global variable Alphabet that lists all the characters we intend to encode. We would like to be able to distinguish all characters which print out, as well as blanks (that is, those which you have keys for on your keyboard). To avoid typing in the full list of characters we want4.13, we generate a list of all the integers less than 256 and convert it to a character string with convert(,bytes). Then we use Select and IsPrintable to pick out the usual printable characters. Finally, since we would like to have a space and a newline as characters in our alphabet, we add them to the resulting string with cat.

> 
  Alphabet := cat("", Select(IsPrintable,convert([seq(i,i=1..255)],bytes)));


\begin{maplelatex}
\begin{displaymath}
\mbox{\lq\lq $\backslash$n$\backslash$t~~!$\ba...
...abcdefghijklmnopqrstuvwxyz\{$\vert$\}$\sim$''}
\end{displaymath}\end{maplelatex}


We will use this particular alphabet regularly in the next few sections.


Next, we define two functions which perform the analogue of convert(,bytes), but with our special alphabet. ListToString will take a list of integers and replace it with the character from that position in Alphabet, and StringToList does the reverse process. For each character in the input string, StringToList uses SearchText to find its position in Alphabet. We need to subtract one from this position because we would like our characters to be numbered from 0 rather than 1. Thus, in the Alphabet above, \t is character 0, and the numeric code for $ \sim$ is 96. Alphabet is declared as a global variable.

> 
  StringToList := proc(text::string)
    local i;
    global Alphabet;
    [seq(SearchText(text[i],Alphabet)-1, i=1..length(text))];
  end:

> 
  ListToString := proc(numlist::list(nonnegint))
    local i;
    global Alphabet;
    cat(seq(Alphabet[numlist[i]+1], i=1..nops(numlist)));
  end:

Now the Caesar cipher is written in terms of these functions. Note that since 0 corresponds to a printable character, we don't have to add and subtract 1 as before.

> 
  Caesar2:= proc(plaintext::string, shift::integer)
    local textnum,codenum,i,p;
    global Alphabet;
  

  p := length(Alphabet);   textnum := StringToList(plaintext);   codenum := [seq( modp(textnum[i]+shift, p), i=1..length(plaintext)) ];   ListToString(codenum);   end:

It works as follows.

Let's try it out.

> 
  Caesar2("Veni, Vidi, Vici",3);


\begin{maplelatex}
\begin{displaymath}
\mbox{\lq\lq Yhql/\char93 Ylgl/\char93 Ylfl''}
\end{displaymath}\end{maplelatex}

To decode, we can just use the negative of the shift amount.

> 
  Caesar2(


\begin{maplelatex}
\begin{displaymath}
\mbox{\lq\lq Veni, Vidi, Vici''} \end{displaymath}\end{maplelatex}

> 
  text:="I have heard the mermaids singing, each to each. 
  I do not think that they will sing to me.";


\begin{maplelatex}
\mapleinline{inert}{2d}{text := ''I have heard the mermaids s...
...think $\backslash$} \\
\mbox{that they will sing to me.''} }
}
\end{maplelatex}


In this sample, we have used a text which contains a newline character. Maple represents this as \n inside a text string. Since we will treat the newline as a regular character, it too will encode to something. If you look carefully at the output below, you can probably pick it out.

> 
  Caesar2(text,64);


\begin{maplelatex}
\mapleinline{inert}{2d}{''('G@UD'GD@QC'SGD'LDQL@HCR'RHMFHMFl'...
...sh$} \\
\mbox{('CN'MNS'SGHMJ'SG@S'SGDX'VHKK'RHMF'SN'LDn''} }
}
\end{maplelatex}

> 
  Caesar2(


\begin{maplelatex}
\mapleinline{inert}{2d}{''I have heard the mermaids singing, ...
...think that they $\backslash$} \\
\mbox{will sing to me.''} }
}
\end{maplelatex}

If we would like to see the decrypted text with the newlines expanded, we need to use printf.

> 
  printf(


\begin{maplettyout}
I have heard the mermaids singing, each to each.
I do not think that they will sing to me.
\end{maplettyout}


One thing that we should check is what happens if our message should contain a character that is not in our alphabet. Rather than changing our text, we'll dramatically shorten the alphabet.

> 
  Alphabet:="abcdefghijklmnop_";



Now let us go then, you and I, and re-encode the test message using the new alphabet, but with a shift of zero. Ordinarily, a shift by 0 would not change the text at all. But with the shortened alphabet, something happens to the characters that aren't mentioned.

> 
  Caesar2(text,0);




Can you explain why this happens?



Footnotes

... want4.13
For versions prior to Maple 7, just type in the desired alphabet directly

next up previous
Next: Improved Caesar-like ciphers Up: fsqFsHn sGGousG Previous: Defining functions with proc;

Translated from LaTeX by Scott Sutherland
2002-08-29