Esempio del test di Kasiski

<< Statistics`DataManipulation`

<< Graphics`Graphics`

Provo a cifrare un testo in chiaro con il cifrario di Vigenere

PlainText = 
      Characters["\
testomessoquidameperprovarexxquestometodoxdammelaprotocolloarovistarechevaomet\
tofoglioxlapidarlo"]

PlainTextNum = ToCharacterCode[PlainText] - 96

\(k = 
ToCharacterCode[
Characters["TECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOLOGIETECNOL"]
] - 65\)

CipherTextNum = 
      Table[Mod[PlainTextNum[[i]] + k[[i]], 26], {i, 1, 
          Length[k]}]

CipherText = 
      FromCharacterCode[
          CipherTextNum + 64] /. "@" -> "Z"

M=CipherText

Faccio il Join dei caratteri e ricosruisco la stringa cifrata

mess = StringJoin[M]

Individuo i trigrammi, cancello i casi ripetuti dalla tabella e utilizzando le funzioni rese disponibili dall'ambiente individuo la posizione dei trigrammi nella stringa

Trigrammi = 
        Table[{StringJoin[M[[i]], M[[i + 1]], M[[i + 2]]], 
            StringPosition[mess, 
              StringJoin[M[[i]], M[[i + 1]], M[[i + 2]]]]}, {i, 
            1, Length[M] - 2}];
Freq = 
        DeleteCases[
          Table[If[Frequencies[Trigrammi][[i]][[1]] > 
                1, Frequencies[Trigrammi][[i]], Inutile], {i, 1, 
              Length[Frequencies[Trigrammi]]}], Inutile];
TabellaTrigrammi = 
        Table[Freq[[i]][[2]][[1]], {i, 1, 
            Length[Freq]}];
FrequenzaTrigrammi = 
        Table[Freq[[i]][[1]], {i, 1, Length[Freq]}];
FrameBox[
        GridBox[Table[{TabellaTrigrammi, FrequenzaTrigrammi}], 
          RowLines -> True, ColumnLines -> True]] // 
      DisplayForm

PosizioneTrigrammi  =  
      Table[Table[Freq[[i]][[2]][[2]][[k]][[1]],  {k, 1, Freq[[i]][[1]]}], {i, 1, Length[Freq]}]
FrameBox[
        TableForm[Table[{TabellaTrigrammi, PosizioneTrigrammi}], 
          TableHeadings -> {{"Trigrammi", "Posizione"}, None}]] // 
      DisplayForm

Key3 = {{75 - 35, Divisors[75 - 35]}, {34 - 4, 
          Divisors[34 - 4]}, {32 - 2, Divisors[32 - 2]}, {88 - 48, 
          Divisors[88 - 48]}, {33  -  3, Divisors[33 - 3]}, {76 - 36, 
          Divisors[76 - 36]},  {75 - 5,  Divisors[75 - 5]},  {35 - 5,  
          Divisors[35 - 5]}}

FrameBox[
        GridBox[Key3, RowLines -> True, ColumnLines -> True]] // 
      DisplayForm

Come sopra, ma per i quadrigrammi. Individuo i quadrigrammi, cancello i casi ripetuti dalla tabella e utilizzando le funzioni rese disponibili dall'ambiente individuo la posizione dei quadrigrammi nella stringa

M = Characters[mess];
Quadrigrammi = 
        Table[{StringJoin[M[[i]], M[[i + 1]], M[[i + 2]], 
              M[[i + 3]]], 
            StringPosition[mess, 
              StringJoin[M[[i]], M[[i + 1]], M[[i + 2]], 
                M[[i + 3]]]]}, {i, 1, Length[M] - 3}];
Freq2 = 
        DeleteCases[
          Table[If[Frequencies[Quadrigrammi][[i]][[1]] > 
                1, Frequencies[Quadrigrammi][[i]], Inutile], {i, 1, 
              Length[Frequencies[Quadrigrammi]]}], Inutile];
TabellaQuadrigrammi = 
        Table[Freq2[[i]][[2]][[1]], {i, 1, 
            Length[Freq2]}];
FrequenzaQuadrigrammi = 
        Table[Freq2[[i]][[1]], {i, 1, 
            Length[Freq2]}];
FrameBox[
        GridBox[Table[{TabellaQuadrigrammi, FrequenzaQuadrigrammi}], 
          RowLines -> True, ColumnLines -> True]] // 
      DisplayForm

PosizioneQuadrigrammi =   Table[
        Table[Freq2[[i]][[2]][[2]][[k]][[1]],  {k, 1, Freq2[[i]][[1]]}], {i, 1, Length[Freq2]}]
FrameBox[
        TableForm[Table[{TabellaQuadrigrammi, PosizioneQuadrigrammi}], 
          TableHeadings -> {{"Quadrigrammi", "Posizione"}, 
              None}]] // DisplayForm

Key4 = {{75 - 35, Divisors[75 - 35]}, {34 - 4, 
          Divisors[34 - 4]}, {32 - 2, Divisors[32 - 2]}, {33 - 3, 
          Divisors[33 - 3]}}

FrameBox[
        GridBox[Key4, RowLines -> True, ColumnLines -> True]] // 
      DisplayForm