Pièce jointe « crypto.py »
Téléchargement 1 #!/usr/bin/python3
2
3 def cesar1_plage(car,k,a='a',z='z'):
4 """
5 Retourne un caractère obtenu par décalage dans un alphabet.
6
7 L’alphabet est représenté comme une plage de points de codes consécutifs dans
8 la norme Unicode_.
9
10 En supposant que `car` se trouve dans la plage de codes entre `a` et `z`, le
11 code du caractère retourné est obtenu en ajoutant `k` au décalage entre `a`
12 et `car`, modulo la longueur de la plage, afin de rester entre `a` et `z`.
13
14 Par défaut, la plage considérée est celle des caractères latins minuscules.
15
16 En dehors de la plage `a`-`z`, comportement du programme n’est pas spécifié.
17
18 Exemples d’utilisation :
19 >>> print(cesar1_plage('s',12))
20 e
21 >>> print(cesar1_plage('V',12,'A','Z'))
22 H
23 >>> print(cesar1_plage('a',-1,'a','f'))
24 f
25
26 .. _Unicode: https://fr.wikipedia.org/wiki/Unicode
27 """
28
29 a_ = ord(a)
30 z_ = ord(z)
31 car_ = ord(car)
32
33 longueur = z_ - a_ + 1
34 decalage = (car_ - a_ + k) % longueur
35
36 return chr(a_+decalage)
37
38
39 def cesar1(car,k):
40 """
41 Retourne le code de César de rang `k` d’un caractère alphanumérique.
42
43 Pour permettre le codage de messages courants, sans perdre les espaces ni la
44 ponctuation, on effectue le codage de César à l’intérieur de différentes plages
45 (lettres latines minuscules et majuscules, plus les chiffres), les autres
46 caractères restant inchangés.
47
48 Exemples d’utilisation :
49 >>> print(cesar1('s',12))
50 s
51 >>> print(cesar1('V',12))
52 H
53 >>> print(cesar1('3',12))
54 5
55 >>> print(cesar1('!',12))
56 !
57 >>> print(cesar1('é',12))
58 é
59 """
60
61 plages = (
62 ('a','z'),
63 ('A','Z'),
64 ('0','9'),
65 )
66
67 for a,z in plages:
68 if a <= car <= z:
69 return cesar1_plage(car,k,a,z)
70 return car
71
72
73 def cesar(message, k, decode=False):
74 """
75 Retourne le code de César d’un `message`.
76
77 Pour le décodage, le même algorithme convient : il suffit de prendre la clé
78 opposée. On propose une option `decode` qui le fait.
79
80 Par souci d’uniformité avec l’algorithme suivant, on peut donner la clé sous
81 la forme d’une chaîne (qui doit être l’écriture d’un entier).
82
83 Exemple d’utilisation :
84 >>> print(cesar('Voilà un super message !',12))
85 Hauxà gz egbqd yqeemsq !
86 >>> print(cesar('Hauxà gz egbqd yqeemsq !',12,True))
87 Voilà un super message !
88 >>> print(cesar('Hauxà gz egbqd yqeemsq !','-12'))
89 Voilà un super message !
90 """
91
92 k = int(k)
93 if decode:
94 k = -k
95
96 code = ""
97 for car in message:
98 code = code + cesar1(car,k)
99 return code
100
101
102 def vigenere(message, cle, decode=False):
103 """
104 Retourne le code de Vigenère d’un `message`.
105
106 Le code est paramétré par une chaîne `cle` : chaque caractère de la clé sert
107 successivement de référence pour définir un décalage, par comparaison avec le
108 caractère ``a``.
109
110 Quand `decode` est vrai, on soustrait le décalage au lieu de l’ajouter, ce
111 qui a pour effet de décoder un message codé.
112
113 Exemple d’utilisation :
114 >>> print(vigenere('Voilà un super message !','lacle'))
115 Gokwà up wfpgc xeudere !
116 >>> print(vigenere('Gokwà up wfpgc xeudere !','lacle',True))
117 Voilà un super message !
118 """
119
120 code = ""
121 i = 0
122 for car in message:
123 k = ord(cle[i])-ord('a')
124 if decode:
125 k = -k
126 code = code + cesar1(car,k)
127 i = (i+1) % len(cle)
128 return code
129
130
131 # Ici on fournit des fonctions qui seront utiles pour interagir avec
132 # l’utilisateur (ce n’était pas demandé dans le sujet).
133
134 def dialogue_chiffre(chiffre,decode):
135 """
136 Code ou décode un message suivant une clé, tous deux fournis par l’utilisateur.
137 """
138 message = input('Entrez le message : ')
139 k = input('Entrez la clé : ')
140 print('On obtient : ', chiffre(message,k,decode))
141
142
143 def dialogue_choix():
144 """
145 Propose à l’utilisateur de choisir un algorithme pour coder ou décoder.
146
147 On renvoie un couple ``(algorithme,decode)`` où `algorithme` est l’algorithme
148 utilisé, et `decode` est un booléen qui indique si on décode.
149
150 Si le choix de l’utilisateur n’est pas dans les options proposées, on renvoie
151 ``None``.
152 """
153 options = (
154 ('v', 'Vigenère', vigenere),
155 ('c', 'César', cesar),
156 )
157 print('Faites votre choix parmi les actions suivantes :')
158 for option, nom, _ in options:
159 print(' ('+option.lower()+')','Coder un message avec la méthode de',nom)
160 print(' ('+option.upper()+')','Décoder un message avec la méthode de',nom)
161 choix = input('Entrez la lettre correspondant à votre choix : ')
162 for option, _, algorithme in options:
163 if choix == option.lower():
164 return algorithme, False
165 if choix == option.upper():
166 return algorithme, True
167 return None
168
169
170 # La variable « magique » `__name__` est automatiquement initialisée par
171 # python. L’utilisation qu’on en fait ci-dessous sera expliquée plus tard.
172 if __name__ == '__main__':
173 choix = dialogue_choix()
174 if choix != None:
175 dialogue_chiffre(*choix)
176 else:
177 print('Choix invalide : on sort !')
Fichiers joints
Pour vous référer aux pièces jointes d'une page, utilisez attachment:filename, comme indiqué ci-dessous dans la liste de fichiers. N'utilisez pas l'URL du lien [get], car elle peut changer et donc être facilement cassée.Vous n'êtes pas autorisé à joindre un fichier à cette page.