Partie C3 · exercices 13 à 19

Le code de César en Python

ord, chr et un petit problème de bouclage : écrire un crypteur-décrypteur

Demander à Python de décaler des lettres ne marche pas tout seul : il n'existe pas de fonction intégrée pour cela. Il faut l'inventer. Pour Python, les lettres n'ont pas de sens particulier : ce sont des caractères stockés sous forme de nombres. Notre but est d'écrire une fonction cryptCesar(texte, cle).

Deux fonctions à connaître

  • ord("A") donne le numéro du caractère A dans la table ASCII (ici 65).
  • chr(65) fait l'inverse : elle donne le caractère qui a ce numéro (ici "A").

Les lettres majuscules A à Z ont les numéros 65 à 90.

La table ASCII est consultable sur ascii-code.com.

ExercicesDécouvrir ord et chr

EX 13Je découvre 🌶️prise en main

Exercice 13 — Des lettres aux nombres

Dans la console de Python :

  1. Teste chr(65), chr(66), puis quelques nombres entre 65 et 91. Qu'obtiens-tu ?
  2. Teste ord("A") et ord("B"). Devine ce que donneront ord("F") et ord("Z"), puis vérifie.
  3. À quoi sert la fonction ord ? et la fonction chr ?
Indice

Le numéro d'une lettre augmente de 1 quand on passe à la lettre suivante de l'alphabet.

📝 réponses dans ton compte rendu, exercice 13

EX 14Je découvre 🌶️prise en main

Exercice 14 — Le décalage vu par Python

  1. Compare ord d'une lettre de départ et ord de la lettre qu'elle devient avec la clé 3 (tableau du cours C2). Fais quelques exemples, puis généralise.
  2. Complète l'expression qui transforme lettre en lettre chiffrée : chr(ord(lettre) + ...). Vérifie avec "G", "M" et "R".
Indice

Pour A → D : ord("D") - ord("A"). Essaie avec d'autres lettres, le résultat est toujours le même.

📝 réponses dans ton compte rendu, exercice 14

EX 15Je comprends 🌶️🌶️application

Exercice 15 — Les cas limites

  1. Que devrait afficher la méthode pour "X", "Y" et "Z" avec la clé 3 ? Est-ce le cas avec chr(ord(lettre) + 3) ? Pourquoi ?
  2. Complète : ord("X") + 3 = .... alors qu'on voulait "A", de code ASCII .... ; même chose pour "Y" et "Z". Quel est l'écart entre les codes dans chaque paire ?
  3. Complète le correctif : if ord(lettre) + 3 > ... : puis nouvelleLettre = chr(ord(lettre) + 3 - ...), sinon nouvelleLettre = chr(ord(lettre) + ...).
Indice

On veut retomber sur A, B, C : il faut « revenir au début de l'alphabet » en retirant 26 (la longueur de l'alphabet).

📝 réponses dans ton compte rendu, exercice 15

EX 16Je comprends 🌶️🌶️application

Exercice 16 — Et pour déchiffrer ?

  1. Quand la formule chr(ord(lettre) - 3) pose-t-elle problème ? (pour quelles lettres ?)
  2. Adapte le correctif : if ... : puis nouvelleLettre = chr(ord(lettre) - 3 + 26), sinon nouvelleLettre = ....
Indice

Pense aux lettres du début de l'alphabet : que donne ord("A") - 3 ?

📝 réponses dans ton compte rendu, exercice 16

CoursUne fonction générale

On veut maintenant que la clé puisse être n'importe quel nombre. Si elle est positive, la fonction chiffre ; si elle est négative, elle déchiffre. Par exemple, un texte chiffré avec la clé 5 se déchiffre avec la clé −5.

EX 17Je programme 🌶️🌶️🌶️plusieurs étapes

Exercice 17 — La fonction cryptCesar

Enregistre le programme ci-dessous sous NOM_Prenom_ex09.py dans ton éditeur, puis complète les trois endroits marqués ... en t'inspirant des exercices précédents. Les lettres sont en majuscules, sans accent.

cryptcesar.py
def cryptCesar(texte, cle):
    """la clé du codage sera comprise entre -26 et 26"""
    textdep = texte.upper()
    textfin = ""
    for lettre in textdep:
        if 65 <= ord(lettre) <= 90:   # on ne crypte que les lettres
            if ord(lettre) + cle > ...:          # à compléter
                textfin += chr(ord(lettre) + cle - 26)
            elif ...:                            # à compléter
                textfin += chr(ord(lettre) + cle + 26)
            else:
                ...                              # à compléter
        else:                         # la ponctuation est reproduite
            textfin += lettre         # sans changement
    return textfin
  1. Complète le programme.
  2. Teste-le avec print(cryptCesar("ANTIQUITE", 3)), puis print(cryptCesar("DQWLTXLWH", -3)).
  3. Explique la ligne textdep = texte.upper() et la raison de sa présence.
Indice 1

La condition de la première ligne à compléter correspond au cas « on dépasse Z ».

Indice 2

La deuxième est le cas « on passe avant A ».

Indice 3

Pour la ligne upper(), essaie print(ord("a")) : les minuscules ont d'autres numéros que les majuscules.

💾 NOM_Prenom_ex17.py

Les accents trahissent

Un É a un numéro ASCII étendu qui n'est pas entre 65 et 90 : il est recopié sans changement. Un message chiffré contenant des accents laisserait donc du texte lisible. On écrit donc les messages sans accent.

ExercicesJe m'en sers

EX 18Je programme 🌶️🌶️🌶️plusieurs étapes

Exercice 18 — Les 25 clés d'un coup

Avec ta fonction cryptCesar, écris une boucle qui essaie les 25 clés :

brute.py
message = "HQ YROHU OD FOH HVW OH VHFUHW"
for cle in range(1, 26):
    print(cle, cryptCesar(message, -cle))
  1. Exécute ce programme. Quelle est la clé utilisée pour chiffrer, et quel est le message ?
  2. Pourquoi un ordinateur casse-t-il un code de César beaucoup plus vite qu'un humain ?
Indice

Repère la ligne qui a du sens en français.

💾 NOM_Prenom_ex18.py

EX 19Je dépasse 🌶️🌶️🌶️🌶️défi

Exercice 19 — Défi : avec le reste de la division

Il existe une autre écriture qui évite les if. Elle utilise %, le reste de la division euclidienne (vu dans le cours Python).

cesar2.py
def cesar2(texte, cle):
    resultat = ""
    for lettre in texte.upper():
        if 65 <= ord(lettre) <= 90:
            resultat += chr((ord(lettre) - 65 + cle) % 26 + 65)
        else:
            resultat += lettre
    return resultat
  1. Teste cesar2("ANTIQUITE", 3) puis cesar2("DQWLTXLWH", -3).
  2. Calcule à la main (23 - 65 + 3 + 65) % 26, puis compare avec cryptCesar("X", 3). Que remarques-tu ?
  3. Pourquoi le résultat de % reste-t-il toujours entre 0 et 25 ?
Indice

On soustrait 65 pour travailler avec des rangs de 0 (A) à 25 (Z), on décale, on « boucle » avec % 26, puis on rajoute 65.

💾 NOM_Prenom_ex19.py