Partage
  • Partager sur Facebook
  • Partager sur Twitter

chiffrement de cesar

exercice

6 mars 2013 à 22:18:19

Bonjour =)   :D

J'ai essayer de faire un petit programme assez simple qui à un rapport avec le célèbre chiffrement de césar.

si on rentre : le message a crypté -c 3 -> le petit -c veut dire que l'on veut crypté le message et le nombre derrière peut aller de 0 à 26 : la valeur de décalage.

si on rentre : le message a décrypté -d 3 -> le petit -d veut dire que l'on veut décrypté le message et pareil que la première pour le nombre derrière ( valeur de décalage)

si on rentre : le message a decrypté -all -> teste toutes les combinaisons possibles.

si le champs du texte est vide -> on affiche : "Le champ du texte est vide"

C'est assez sympa sachant que je débute en python je trouve que c'est un bon entraînement !

Voici mon code, je débute alors je penses que beaucoup auront de chose à dire sur mon code, il ne fonctionne pas et je ne comprend pas pourquoi :(

import re
 
 
shift = 3
lettres = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
transform = lettres[shift:] + lettres[:shift]
 
dico = dict(zip(lettres, transform))
 
chaine = raw_input("Veuillez tapez votre message: ")
 
 
 
if re.match(r'(.*) -c', chaine):
  crypt = []
  for x in chaine:
    crypt.append(dico.get(x, x))
elif re.match(r'(.*) -d', chaine):
  decrypt = []
  for x in chaine:
    decrypt.append(x)
else: print 'Mauvaise syntaxe'
 
if crypt != []:
  print 'Message crypte', ''.join(crypt)
  print 'Message decrypte', ''.join(decrypt)
else: print 'Le champ du message est vide'

Merci ! ^^

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2013 à 14:58:47

Salut,

Tu définis les variables crypt et decrypt dans des boucles if, ainsi seul l'un des deux existe la première fois et le programme plante des que tu souhaites faire une opération dessus (par exemple accéder à leur contenu ou les afficher à la fin). Je te conseille de les définir toutes les deux dès le début du programme.

Par ailleurs, ton programme est encore trop spécifique (il ne décode pas les messages). Et il ne permet pas d'afficher le message décrypté (il manque un teste entre les lignes 25 et 26.

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2013 à 15:15:23

Bonjour,

Je trouve que pour un débutant, tu ne t'attaques pas à ce problème sous l'angle le plus facile (re, dict(zip(...)) )!

Pour moi, tu peux laisser tomber l'option chiffrement/déchiffrement. Pour déchiffrer, il te suffit d'appliquer le programme avec le décalage utilisé pour le chiffrement * -1. Autant alors faire un input pour demander le décalage souhaité.

Ensuite, tu initialises tes variables crypt et decrypt dans des blocs conditionnels, ce qui implique que si tes condition ne sont pas respectées, tu n'initialiseras jamais la variable. Normalement ton interprêteur devrait t'insulter pour ça :) ==> NameError: name 'crypt' is not defined.

Ton programme est vraiment simplifiable :-)

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2013 à 18:30:13

Je n'ai pas tout compris dans ton code (je ne connait pas re) donc j'ai essayé de le faire à ma façon et je suis arrivé à ça :

liste_lettre=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
pas=int(input("Saisissez le pas :"))
while pas>26:
    pas-=26
phrase=(input("Votre phrase : ")).lower()
phrase_codee=[]
phrase=phrase.split()
for mot in phrase:
    liste_mot=[]
    for lettre in mot:
        i=liste_lettre.index(lettre)
        if i+pas>25:
            i-=26
        liste_mot.append(liste_lettre[i+pas])
    phrase_codee.append("".join(liste_mot))
print(" ".join(phrase_codee))


Le code de César est ici le pas 2.

ce code marche 

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2013 à 18:43:42

Tout d'abord, merci pour vos réponses ! Cela m'a bien aider :)

J'ai donc changer la syntaxe de mon code comme voici :

>>> Par ailleurs, ton programme est encore trop spécifique (il ne décode pas les messages).

J'essaye de mettre en place la structure du code avant de m'attaquer à l'interprétation =)

import re 

shift = 3
lettres = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 
transform = lettres[shift:] + lettres[:shift] 

dico = dict(zip(lettres, transform)) 

chaine = raw_input("Veuillez tapez votre message: ") 

if chaine != '': 
  if re.match(r'(.*) -c$', chaine):
    crypt = [] 
    for x in chaine:
      crypt.append(dico.get(x, x)) 
      print 'Le message code est: ',''.join(crypt)
    
  elif re.match(r'(.*) -d$', chaine):
    decrypt = []
    for x in chaine:
      decrypt.append(x)
      print 'Le message decode est:',''.join(decrypt)
  else:print'Mauvaise syntaxe' 
else:print'Le champ du texte est vide'

Sauf que je ne sais pas comment faire pour éviter la répétition des caractères :

Si je tape salut -c, cela m'affiche:

Le message code est:  v
Le message code est:  vd
Le message code est:  vdo
Le message code est:  vdox
Le message code est:  vdoxw
Le message code est:  vdoxw
Le message code est:  vdoxw -
Le message code est:  vdoxw -f

Merci !

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
7 mars 2013 à 19:16:24

Quelques remarques :

  • Pour vérifier qu'une chaîne de caractères n'est pas vide, if chaine: suffit (comme pour les listes où on a bool([]) = False, on a pour la chaîne vide bool('') = False).
  • « Le message codé est » se répète car tu as placé la ligne print 'Le message code est: ',''.join(crypt) dans la boucle for. Désindente-la et tu obtiendras le comportement voulu.
  • D'ailleurs, tu n'as pas besoin de créer une liste explicitement ni d'utiliser la méthode append puis join. Tu peux directement travailler avec la chaîne :

      crypt = ''
      crypt += 'a'
      crypt += 'b'
      print(crypt) # 'ab'
    
  • Tu n'as pas besoin de regex ici : if chaine.endswith(' -c'): et if chaine.endswith(' -d') suffisent.

  • Par contre, tu ferais mieux de gérer les arguments et options avec un module adapté comme argparse, car ta solution est peu flexible et pas très pratique. Là, quand on tape message -c, toute cette chaîne est chiffrée et pas seulement message. Tu pourrais t'en sortir en modifiant ta boucle pour ignorer la fin (for x in chaine[:-3] par exemple), mais ce n'est pas très élégant et peu recommandable.

-
Edité par Anonyme 7 mars 2013 à 22:08:03

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2013 à 19:55:45

Merci Beaucoup ! C'est exactement l'aide que j'attendais. ^^

Déjà pour la première astuce, je connaissais pas et merci de me l'avoir montrer. :D

Pour la deuxième ligne ça se complique, j'ai essayer de désindenter avec n'importe quel moyen mais toujours une erreur.

Je penses qu'avec le nouveau code ça sera plus clair :

shift = 3
lettres = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 
transform = lettres[shift:] + lettres[:shift] 

dico = dict(zip(lettres, transform)) 

chaine = raw_input("Veuillez tapez votre message: ") 

if chaine: 
  if chaine.endswith(' -c'):
    crypt = [] 
    for x in chaine:
      crypt.append(dico.get(x, x)) 
      print 'Le message code est: ',''.join(crypt)
    
  elif chaine.endswith(' -d'):
    decrypt = []
    for x in chaine:
      decrypt.append(x)
      print 'Le message decode est:',''.join(decrypt)
  else:print'Mauvaise syntaxe' 
else:print'Le champ du texte est vide'

Si je décale le print au niveau du if cela me met l'erreur suivante :

# elif re.match(r'(.*) -d$', chaine):
# SyntaxError: invalid syntax

Comment éviter cela? :euh:

Sinon pour supprimer le -c ou -d a la fin de la chaîne je pensais à :

lc = crypt[-1]
lt = crypt[-2] 
crypt.remove(lc)
crypt.remove(lt)

Mais j'avoue que ce n'est pas la meilleure façon de faire et qu'il y a sûrement beaucoup mieux.

Merci !



  • Partager sur Facebook
  • Partager sur Twitter
9 mars 2013 à 19:06:52

Pour supprimer le -c ou -d tu peut utiliser replace :

>>> s = "Salut -c"
>>> s = s.replace(" -c", "")
>>> s
'Salut'
>>> 



-
Edité par Kokopak 9 mars 2013 à 19:07:20

  • Partager sur Facebook
  • Partager sur Twitter
Développeur de GroovySearch (site down pour l'instant)
Anonyme
9 mars 2013 à 19:10:55

Utilise quatre espaces pour indenter ton code, tu t'y retrouveras bien mieux.

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
9 mars 2013 à 19:51:40

Déjà

>>> import string
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

Ensuite, tu devrais placer ta chaîne de caractères et ton paramètre lors de l'exécution de ta ligne de commande

Exemple:
python program.py -c ma chaîne a traiter

Pour cela on utilise argv

Ensuite python permet de faire beaucoup de choses qui t'évitent de réinventer la roue comme l'utilisation de maketrans et translate

Bonne continuation... 

  • Partager sur Facebook
  • Partager sur Twitter
9 mars 2013 à 20:25:56

Merci =)

C'est surtout au niveaux de l'indentation du code que je bloque, au niveau de la boucle si quelqu'un peut m'aider ? :-°

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
10 mars 2013 à 19:11:59

electronic78 a écrit:

? o_O

J'allais te dire la même chose...

Plus sérieusement, c'est quoi le problèmes avec l'indentation ? Qu'est-ce qui te gêne ?

Et tu devrais aussi suivre l’excellent conseil de Graphox :

Utilise quatre espaces pour indenter ton code, tu t'y retrouveras bien mieux.

  • Partager sur Facebook
  • Partager sur Twitter
11 mars 2013 à 17:03:23

Non J'ai retenté en indentant correctement et cela marche :D

Merci à tous =)

  • Partager sur Facebook
  • Partager sur Twitter