Le test de Friedman

Etape par étape

extrait = "Entrez ici le texte clair ou chiffré selon vos besoins";

L'instruction suivante supprime tous les accents et écrit le texte en majuscules.

\(\(maj = 
        ToUpperCase[
          StringJoin[
            Characters[
                ToLowerCase[
                  extrait]] /. {"é" -> "e", "è" -> "e", "ê" -> "e", "ë" -> "e", "à" -> "a", "â" -> "a", "î" -> "i", "ï" -> "i", "ö" -> "o", "ô" -> "o", "ü" -> "u", "û" -> "u", \ "ç" -> "c"}]];\)\)

Dans un ordinateur, les lettres majuscules sont codées en code ASCII, du numéro 65 (A) au numéro 90 (Z).

ascii = ToCharacterCode[maj]

On compte le nombre total de caractères (espaces et signes de ponctuation non compris).

long = 
      Length[Select[ascii,  (# < 91  &&  # > 64)  &]]

On calcule les nombres d'apparition de chaque lettre...

nombresLettres = Table[N[Count[ascii, j]], {j, 65, 90}]

Il ne reste plus qu'à calculer l'indice de coïncidence (IC):

For[{IC = 0, j = 1}, j ≤ 26, 
        IC += nombresLettres[[j]]*(nombresLettres[[j]] - 
                1); j++];
IC = IC/(long*(long - 1))

Modules Friedman

Ce premier module traduit en codes ascii les lettres du texte. Il supprime avant cela les accents et caractères spéciaux.

\(\(codeAscii[texte_]\  := \ 
        Module[
{maj, 
            lesCodesAscii}, 
maj = 
            ToUpperCase[
              StringJoin[
                Characters[
                    ToLowerCase[
                      texte]] /. {"é" -> "e", "è" -> "e", "ê" -> "e", "ë" -> "e", "à" -> "a", "â" -> "a", "î" -> "i", "ï" -> "i", "ö" -> "o", "ô" -> "o", "ü" -> "u", "û" -> "u", \ "ç" -> "c"}]]; 
lesCodesAscii = ToCharacterCode[maj]; 
Select[
            lesCodesAscii, \ \((# < 91\  && \ # > 
                    64)\)\  &]
];\)\)

nombresAscii = codeAscii[extrait]

Ce deuxième module renvoie l'incide de coïncidence de Friedman. Le paramètre est une liste de codes ascii entre 65 et 90 (A à Z).

friedman[ascii_]  :=  
        Module[
{j, long, nombresLettres,  
            IC}, 
long = 
            Length[ascii]; 
nombresLettres = 
            Table[N[Count[ascii, j]], {j, 65, 
                90}]; 
For[{IC = 0, j = 1}, 
            j ≤ 26, 
            IC += nombresLettres[[j]]*(nombresLettres[[j]] - 
                    1); j++]; 
IC = 
            IC/(long*(long - 1)); 
N[IC, 
            3]
];

friedman[nombresAscii]

Utilisation du test de Friedman pour trouver la longueur d'une clef du chiffre de Vigenère

texteAnglaisChiffré = "CHREE VOAHM AERAT BIAXX WTNXB EEOPH \
BSBQM QEQER BWRVX UOAKX AOSXX WEAHB WGJMM QMNKG RFVGX WTRZX WIAKL XFPSK AUTEM \
NDCMG TSXMX BTUIA DNGMG PSREL XNJEL XVRVP RTULH DNQWT WDTYG BPHXT FALJH ASVBF \
XNGLL CHRZB WELEK MSJIK NBHWR JGNMG JSGLX FEYPH AGNRB IEQJT AMRVL CRREM NDGLX \
RRIMG NSNRW CHRQH AEYEV TAQEB BIPEE WEVKA KOEWA DREMX MTBHH CHRTK DNVRZ CHRCL \
QOHPW QAIIW XNRMG WOIIF KEE";
nombresAscii = codeAscii[texteAnglaisChiffré];

longClefMax = 8;
long = Length[nombresAscii];
\(For[i = 1, 
      i ≤ 
        longClefMax, 
{
Print["Intervalle : ", 
          i]; 
listeIC = {}; 
For[j = 1, 
          j ≤ 
            i, 
{
séquence = {}; 
For[k = 0, k + j < long, 
              AppendTo[séquence, nombresAscii[\([j + k]\)]]; 
              k += i]; 
AppendTo[listeIC, 
              friedman[
                séquence]]
}; 
\(j++\)
]; 
\(Print[
            listeIC];\)
}; 
\(i++\)
]\)