Voilà, je planche sur l'algorithme de chiffrement par décalage (chiffre de César et il y a un point que je ne comprends pas : il faut que ce soit circulaire ('z' + 2 donne 'b'), donc modulo 26. Jusqu'ici pas de soucis. Mais pourquoi devoir calculer la distance de la lettre jusqu'à 'a' ?
(ord('z') + 2) - ord('a')
Et pourquoi ensuite ré-ajouter la valeur ASCII de 'a' ?
Voici pourquoi: >>> 'a'+2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate str (not "int") to str On ne peut pas faire des calculs avec des caractères Je fais n=ord('a') pour avoir le code de 'a' (qui est 97) Je peux faire des calculs avec ord('a') ou ord('z') Par exemple ord('y') - ord('a') me donne l'ordinal de 'y' soit 24 (25 pour 'z') J'ajoute 3 et je fais le modulo 24+3=27 27%26=1 chr(ord('a')+1) me donne ra 'b'
Le Tout est souvent plus grand que la somme de ses parties.
Et pourquoi ensuite ré-ajouter la valeur ASCII de 'a' ?
chr(((ord('z') + 2) - ord('a')) % 26 + ord('a'))
Merci pour votre aide
C'est une raison "mathématique". Les caractères de a à z sont numérotés consécutivement par ord. On va dire que a est numéroté par x0, ensuite tu as x1, x2, etc, jusqu'à x25. Tu veux appliquer le chiffrement de César au caractère au numéro xi avec xi=x0+i. Tu as compris que le chiffrement se faisait par un décalage de 2 donc que la lettre chiffrée était xj=x0+(i+2)%26. Le problème est que tu dois désormais exprimer ce numéro uniquement en fonction de xi. Or, xi=x0+i donc i=xi-x0 donc xj=x0+(xi-x0+2)%26 ou encore xj=(xi+2-x0)%26+x0 qui est exactement ta formule.
Maintenant cette façon de faire est je trouve assez absurde car il faut faire un calcul déraisonnable au lieu d'une bête addition dans 24 cas sur 26. Il suffit juste de traiter à part les deux dernière lettres (y et z). Illustration en code :
def cesar_alt(c):
if c not in "yz":
return chr(ord(c)+2)
elif c=="y":
return "a"
else:
return "b"
def cesar_alt_bis(c):
return chr(ord(c)+2) if c not in "yz" else "a" if c=="y" else "b"
def cesar(c):
return chr(ord("a")+(ord(c)+2-ord("a"))%26)
for c in "azertyuiopmlkjhgfdsqwxcvbn":
print(c, cesar(c) == cesar_alt(c)== cesar_alt_bis(c))
a True
z True
e True
r True
t True
y True
u True
i True
o True
p True
m True
l True
k True
j True
h True
g True
f True
d True
s True
q True
w True
x True
c True
v True
b True
n True
EDIT. Il y a plusieurs autres façons de faire.
- Edité par PascalOrtiz 16 octobre 2021 à 10:02:04
Effectivement, c'est une des façons de faire. Une autre méthode classique est le recours à un dictionnaire, c'est comme ça que le rot13 de Python est implémenté.
Une autre méthode est d'utiliser la méthode statique maketrans :
Je n'avais pas envisagé le problème sous un angle mathématique.
C'est plus clair, je dois encore m'y faire mais c'est déjà plus clair.
Merci
Chiffre de césar
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Découverte Python Doc Tkinter Les chaînes de caractères
Découverte Python Doc Tkinter Les chaînes de caractères