Vigenere Cipher

The Vigenere Cipher is similar to the shift cipher but instead of adding a number
to each character, it operates on blocks of characters. A secret key word of length k
is added to blocks of k letters. To implement this cipher, we need a function that
will break a list into sublists with k elements each. To implement this, we must ensure that
the length is a multiple of k. This can be done by appending the necessary number of
characters to the end of list when the string length is not a multiple of k. A function to
break a text into blocks of k letters is given below. The built -in function Partition can also
be used but we must ensure that the length is a multiple of k.

In[19]:=

  breaktext[m_String,  key_]:= Module[ {k=StringLength[key] },
               text=ToNumericForm[m];
                n=Length[text];
                plaintext={};
                While[ n>=k,
                   AppendTo[plaintext,Take[text,k]];
                   text=Drop[text,k];
                   n=n-k;];
                If[ 0<n<k, AppendTo[plaintext,
                            Flatten[AppendTo[text,Table[Random[Integer,26],
                                     {i,1,k-n}]]]]];
                 Return[plaintext]]

In[20]:=

  breaktext[ " abc def ghijklmop", "abcd"]

Out[20]


In the Vigenere cipher, we take a plaintext M and add a key word K as in the
following example.

Suppose M= I came I saw Iconquered and the key is Egypt,

the we add the two strings

IcameIsawIconquenred
EgyptEgyptEgyptEgypt

by doing arithmetic modulo 26. For this we generate the character codes of the two strings
and then add them using the Map command.

In[21]:=

  
  vigenere[M_String, K_String]:= 
                Module[ { l},
                  
                  l=breaktext[M,K];
  
                  l=Mod[Map[ #+ToNumericForm[K] &,l],26];
                  l=Flatten[l]+97;
                  Return[FromCharacterCode[l]]]

In[22]:=

  
  vigenere[ "I came Isaw I conquered", "Egypt"]

Out[22]

The cryptanalysis of the Vigenere cipher also requires a frequency analysis of
digrams and trigrams, two and three letter strings of the English alphabet. The program is
similar to the frequency analysis of the letters of the alphabet that was given above.

The program finds all the two letter sequences in the text and counts their frequency. The second
argument is an integer a that can be set to return only those digrams that occur at least
a times.

In[23]:=

  digrams[cipher_,a_]:= 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>a, 
                       AppendTo[s, {str,p}]];
                     i++];
                     Return[Union[s]]]
                     


Exercise: Rewrite the program without using a While statement.

Exercise: Modify the program to count the frequency of trigrams. Trigrams are sequences
of three letters. The frequency analysis of trigrams is very useful because "THE" is the
most common trigram in the English language.

Up to Procedural Programming