Basic Routines for Cryptography

Here are a few Mathematica routines for use with the crytposystems  discussed in 
section  15.  The routines wil convert a text into numeric form and vice-versa.  
There are also programs for counting the relative occurrence of letters, digrams and trigrams.

Conversion Routines:

These use the string manipulation commands of Mathematica. Recall that we convert a string of English text into numeric form by removing all punctuation and  converting A to 0, B to 1,... Z to 25. This is accomplished by the following procedure which returns  list of numbers.

ToNumericForm[m_String]:= Module[ {text},
              text=ToLowerCase[m];
              If[Length[StringPosition[text," "]]>=1,
              text= StringReplace[text," "->""]];
              text=ToCharacterCode[text]-97;
              Return[text]]

ToNumericForm["ABCDE FGHIJ KLMNO PQRST UVWXY Z"]

ToNumericForm["abcdef"]

We also need  the inverse of this operation which converts a list of data into a text sting.  You will have to introduce appropriate punctuation.

ToTextForm[ plain_List]:=FromCharacterCode[plain+97]

ToTextForm[ {0,1,2,3,4,5}]

Frequency Distribution:

The first function will give the frequency distribution in a cipher. 
  The second two function will count the occurrence of digrams and trigrams.   Since   most digrams and trigrams occur only once, it is  to print only those which occur more than m times, where m  is the second argument of the functions.

freq[str_]:= Transpose[ {  Characters["abcdefghijklmnopqrstuvwxyz"],
 Map[ Length[StringPosition[str,ToString[#]]] &,
              Characters["abcdefghijklmnopqrstuvwxyz"]]
             }]

digrams[cipher_,m_]:= Module[ {k=1,str,l,i,p, s={}},
                    i=1;
                   l=StringLength[cipher];  
                   While[i< l-4  ,
                   str=StringTake[cipher,{i,i+1}];
                   p=Length[StringPosition[cipher,str]];
                   If[p>m, 
                     AppendTo[s, {str,p}]];
                   i++];
                   Return[Union[s]]]

trigrams[cipher_,m_]:= Module[ {k=1,str,l,i,p, s={}},
                    i=1;
                   l=StringLength[cipher];  
                   While[i< l-5  ,
                   str=StringTake[cipher,{i,i+2}];
                   p=Length[StringPosition[cipher,str]];
                   If[p>m, 
                     AppendTo[s, {str,p}]];
                   i++];
                   Return[Union[s]]]

Consider an example:

ciphertext="ganvvnatozseumdvmulployelqwymtcmynaigbpcmjfwgzpjlp
pminwzpiswgoddrcgvojrkzmqjkjomczxywzpjjtgccnizfyfvrkabjwykabyziuw
llrvzlmcoshmqnfieemynenszpiijkazolrlbszmiaulbmesbtjrtgcwy
kisaavvvsttockgesdgylpptlrvxczzzgcdgcswmydruanqzvvfbhzeiw
ttvfcwbznivavnjviwkegclfbtgejzqqoswsbezrkawywvzfodolvgjuz
gkavejjfucdolvjmtnxywepgpbfwhigrkmzaxywkszwjtwlmhjwmyavfe
wyzeeytpolvoptoijiclmijhzzovlvmlihugutiekwapzrwjwxvrflppm
xywjwvgbkyfvvvkaevrugcensdwbsdrxdqvzxyaasvwysxazrvvqyolvu
tzphpowcghfxkcttksvlgcjaalloh"

freq[ciphertext]

digrams[ciphertext,3]

trigrams[ciphertext,3]

trigrams[ciphertext,2]