Chap. 13 — Cryptanalyse : analyse fréquentielle

Chap. 13 — Cryptanalyse : analyse fréquentielleIntroductionManipulation de fichiers texte avec PythonDeux types de fichiers logiquesCréation d'un objet de type fichier avec PythonModes d'ouverture des fichiersOpérations courantes sur les fichiersExemplesAffichage du contenu d'un fichier, ligne par ligneAffichage du contenu d'un fichier, ligne par ligneAffichage du contenu d'un fichier après l'avoir chargé entièrement en mémoire dans une liste dont les éléments sont les lignesAffichage du contenu d'un fichier après l'avoir chargé entièrement en mémoire dans une seule chaîne de caractèresLa manipulation des fichiers impose la transformation de chaînes de caractèresSéparateurs de lignes et autres différences entre systèmes d'exploitationTravail à réaliserExtraction de tous les caractères du romanNettoyage des caractèresTransformation des caractères accentués

Bibliographie. « Divertissements mathématiques et informatiques », Laurent Signac


Introduction

L'analyse fréquentielle est une technique de cryptanalyse qui utilise le fait que, dans les langues basées sur des lettres, celles-ci n'apparaissent pas au hasard : certaines lettres, ainsi que certaines suites de lettres, apparaissent plus souvent que d'autres.

Ces fréquences d'apparition dépendent de la langue. En français, la lettre la plus fréquente est le E. Dans un texte, environ une lettre sur six est un E. Les lettres les moins fréquentes sont le K et le W. Il faut plus de 2000 lettres pour avoir de bonnes chances de trouver un W.

Puisqu'une substitution monoalphabétique, comme le chiffrement de César, transforme une lettre de manière toujours identique, il suffit de repérer dans le texte crypté la lettre qui revient le plus souvent. Il y a de bonnes chances pour qu'elle corresponde au E. Les autres lettres fréquentes sont A, N, S, T et I. Chaque nouvelle lettre découverte en utilisant la méthode des fréquences nous fait progresser dans la voie du déchiffrement.

Remarque. En plus des fréquences des lettres seules, il est possible d'utiliser les fréquences des bigrammes (deux lettres consécutives) ou des trigrammes. Le bigramme le plus fréquent en français est ES.

L'analyse fréquentielle ne peut être utile que si l'on dispose d'une quantité suffisante de données. Nous allons donc être amenés à manipuler de longues chaînes de caractères qu'il est hors de question de « retaper »· Par exemple, le texte qui servira de base à nos statistiques comporte un demi-million de caractères.

Puis, après avoir construit notre propre table de fréquences, basée sur le roman de Jules Verne La Jangada, nous l'utiliserons pour analyser un texte chiffré d'environ 450 caractères et déduirons de cette analyse la totalité du texte en clair et la quasi-totalité de la clé de chiffrement.

Manipulation de fichiers texte avec Python

Deux types de fichiers logiques

Référence : http://pise.info/algo/fichiers.htm

La manipulation d'un fichier dépend de son type :

Dans un fichier texte, toutes les données sont écrites sous forme de texte (chaînes de caractères). Cela veut dire que les nombres y sont représentés sous forme de suites de « caractères-chiffres ». Ces nombres doivent donc être convertis en chaînes de caractères lors de l'écriture dans le fichier. Inversement, lors de la lecture du fichier, on devra convertir ces chaînes en nombres si l'on veut pouvoir les utiliser dans des calculs.

Création d'un objet de type fichier avec Python

En python, on crée un objet fichier grâce à la fonction open :

La fonction open prend, comme arguments, deux chaînes de caractères. La première est le chemin du fichier à ouvrir (absolu ou relatif), la seconde précise dans quel mode il doit l'être (lecture, écriture, etc.). Il est aussi possible, de manière optionnelle, d'indiquer l'encodage du texte dans le fichier à lire.

Remarque. Il faut toujours faire attention à l'encodage utilisé lors de l'édition d'un texte dans un éditeur. Par défaut, en Python 3, les chaînes de caractères sont encodées en utf-8. C'est le réglage par défaut des systèmes d'exploitation modernes. Tout texte non encodé en utf-8 n'est pas détecté comme tel par Python 3 mais comme une séquence d'octets (texte binaire donc) !

Création d'un objet fichier en lecture seule en précisant l'encodage

Modes d'ouverture des fichiers

Opérations courantes sur les fichiers

Exemples

Affichage du contenu d'un fichier, ligne par ligne

Affichage du contenu d'un fichier, ligne par ligne

Affichage du contenu d'un fichier après l'avoir chargé entièrement en mémoire dans une liste dont les éléments sont les lignes

Affichage du contenu d'un fichier après l'avoir chargé entièrement en mémoire dans une seule chaîne de caractères

 

La manipulation des fichiers impose la transformation de chaînes de caractères

Il est nécessaire de savoir très rapidement : découper une chaîne de caractères en sous-chaînes, construire une chaîne de caractères, etc. Les exemples ci-dessous sont donc généralement utilisés lorsqu'on manipule des fichiers contenant du texte :

Séparateurs de lignes et autres différences entre systèmes d'exploitation

Sur les systèmes POSIX (famille des Unix, Linux ou OS X) le séparateur de ligne est le caractère Nouvelle ligne (Newline ou \n). Pour les versions antérieures de Mac OS, c'était le Retour à la ligne (Return ou \r), tandis que les systèmes DOS et Windows utilisent la combinaison des deux (\r\n).

Parmi les autres différences entre systèmes, on trouve le séparateur de répertoires dans les chemins d'accès (POSIX utilise / alors que DOS et Windows utilisent \. Les modules os et os.path permettent de ne pas avoir à se soucier de toutes ces différences.

Travail à réaliser

Extraction de tous les caractères du roman

  1. Télécharger le texte contenant le roman de Jules Verne : La jangada. Remarque. Ce texte a été récupéré sur le site du projet Gutenberg.

  2. Définir la fonction dont la spécification est :

    Remarque : Ne pas oublier d'importer le module typing dans les premières lignes.

  3. Définir et appeler la fonction main suivante :

Nettoyage des caractères

La liste liste_caractères contient des caractères n'appartenant pas à l'alphabet (blancs, ponctuations, etc.). Il est nécessaire de les éliminer.

  1. Importer le module string au début du fichier.

  2. Compléter le code de la fonction suppression_ponctuation suivante :

  3. Sur le même modèle, compléter le code de la fonction suppression_blancs suivante :

  4. Sur le même modèle, compléter le code de la fonction suppression_chiffres suivante :

  5. Définir une fonction appelée nettoyage qui réalise en un seul appel les trois actions réalisées par les trois fonctions précédentes.

  6. Appeler la fonction nettoyage depuis la fonction main :

Transformation des caractères accentués

Dans cette partie nous allons transformer tous les caractères accentués en leur équivalent sans accent.

  1. Définir la fonction trouve_indice dont la spécification est :

  2. Définir la fonction transformation_accents dont une partie du code est :

    Cette fonction doit utiliser la fonction trouve_indice.

  3. Appeler la fonction nettoyage depuis la fonction main :

    Transformation des minuscules en majuscules

    1. Définir la fonction transformation_minuscules dont la spécification est :

      Utiliser les méthodes sur les chaînes de caractères introduites au chapitre 10.

    2. Appeler la fonction transformation_minuscules depuis la fonction main :

    Création des dictionnaires

    L'objet de cette partie est la création d'un dictionnaire dont les clés sont les caractères et les valeurs leur fréquence d'apparition.

    1. Définir la fonction creation_dict_car dont la spécification est :

    2. Définir la fonction dont la spécification est :

    3. Appeler les deux fonctions précédentes depuis la fonction main :

    4. Définir la fonction affichage suivante :

    5. Appeler la fonction affichage depuis la fonction main :

      Le résultat devrait être :


    Solution (texte chiffré)