IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

chiffre de césar


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 8
    Par défaut chiffre de césar
    Salut, j'débute en programmation (et donc en Python), et j'ai tenté de faire l'exercice 1 que j'ai vu ici:
    http://www.unpeud.info/python/introduction?start=12
    Seulement voila, mon programme ne transcrit pas correctement les phrases.
    Il ne transcrit que la dernière lettre, et je trouve vraiment pas pourquoi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    alphabet = list('abcdefghijklmnopqrstuvwxyz')
    alphabet2 = list('abcdefghijklmnopqrstuvwxyz')
    ##print (alphabet)
    phrase = input("Ecrivez une phrase:")
    print(phrase)
    decalage = input("Valeur du decalage?")
    def ceasar():
        x,y,z = 0,1,1
        while x<26:
            y = x+int(decalage)
            z = y - 26
            if(y<26):
                alphabet[x] = alphabet[y]
            else:
                alphabet[x] = alphabet2[z]
            x = x + 1
        print(alphabet)
    ceasar()
    newPhraseList = list(phrase)
    nbLettres = len(phrase)
    newPhrase = ""
    n = 0
    while n<nbLettres:
        newPhrase = newPhrase+""+newPhraseList[n]
        phraseFinal = newPhrase.replace(newPhraseList[n],alphabet[n])
        n = n + 1
        print (phraseFinal)
    J'aimerais surtout comprendre et pas juste avoir la solution, merci d'avance!

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Oula… Y aurait beaucoup à dire sur ce code…

    Bon, d’abord, l’erreur en question.Dans votre boucle finale, vous écrasez à chaque itération phraseFinale par newPhrase, en ne remplaçant que toutes les lettres correspondant à la dernière en cours (attention à replace, elle affecte tous les caractères correspondant au premier paramètre).

    Il y a une autre grosse erreur qui va vous sauter à la figure dès que vous essayerez de crypter un texte de plus de 26 caractères*: alphabet est une liste de 26 éléments, vous ne pouvez pas l’indexer avec n*! À la rigueur (et en se compliquant joyeusement la vie), vous pouvez convertir chaque lettre en son indice dans cette liste avec ord(lettre) - ord(a)…

    En fait, voici comment pourrait s’écrire cette dernière boucle*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    phraseFinal = ""
    while n<nbLettres:
        phraseFinal = phraseFinal + alphabet[ord(newPhraseList[n]) - ord(a)]
        n = n + 1
    print (phraseFinal)
    Maintenant, pour vous dégoûter, voici comment je ferais la même chose*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # On récupère les données.
    phrase = input("Ecrivez une phrase:")
    decalage = int(input("Valeur du décalage?"))  # Conversion direct en int!
     
    # On crée un dictionnaire {lettre_de_départ: lettre_encodée}.
    maping = {}
    for i in range(26):  # Pour chaque nombre de 0 à 25
        i_caesar = (i + decalage) % 26  # Modulo 26, pour toujours avoir un résultat compris entre 0 et 25 inclus (modulo 26 = reste de la division euclidienne par 26).
        # On ajoute à ces nombre la "valeur" de la lettre a, et on les convertit en lettres!
        c_caesar = chr(i_caesar + ord('a'))
        c = chr(i + ord('a'))
        maping[c] = c_caesar
    # On a maintenant un dictionnaire qui à chaque lettre fait correspondre sa valeur codée.
    result = ""
    for c in phrase:  # Pour chaque caractère de phrase...
        result = result + maping[c]
    print(result)
    À noter que ce code peut encore être fortement réduit si on utilise des trucs “avancés” comme les comprehensions et str.translate()*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # On récupère les données.
    phrase = input("Ecrivez une phrase:")
    decalage = int(input("Valeur du décalage?"))  # Conversion direct en int!
     
    # On crée la table de "traduction"
    ord_a = ord('a')
    translate = str.maketrans({chr(i + ord_a): chr(((i + decalage) % 26) + ord_a) for i in range(26)})
     
    # Et on "traduit" la phrase!
    print(phrase.translate(translate))
    Enfin, il faudrait aussi sécuriser le code (vérifier qu’il n’y a pas de caractères interdit dans l’entrée, pas de majuscules, etc...)

  3. #3
    Membre très actif

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Âge : 75
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 211
    Billets dans le blog
    1
    Par défaut Et vlan ... passe-moi l'éponge ;-))
    Là, mont29, si krorys n'est pas fusillé ...

    Ta dernière proposition est ... bluffante pour un débutant mais elle montre également tout le chemin qu'il lui reste à parcourir pour devenir "programmeur" Python

    Bon courage krorys

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 683
    Par défaut
    Salut,

    Python est bluffant car le débutant ne sait pas encore que la réalisation de nombre d'algorithmes courants est bien aidée par des fonctionnalités qu'il ignore encore. Poster dans le forum est aussi un moyen de les découvrir.

    Mais l'intérêt est de se libérer de la réalisation des détails pour se concentrer sur les fonctions de haut niveau.

    Sur ce sujet, le code du PO est assez bien structuré:
    - saisie des informations,
    - construction de la table de translation,
    - translation de la chaine de caractère lue.

    Par contre, le passage par ord et chr oblige à des transformations qui descendent un peu trop vite dans le bit and bytes.

    Le codage s'effectue en associant les lettres de l'alphabet à une rotation. Une chaine de caractère étant une sequence (comme une liste), nous pouvons faire cela sans trop se poser de question sur leur "nature":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
       >>> rotate = lambda seq, c: seq[-c:] + seq[:-c]
       >>> # rotate travaille sur une sequence...
       >>> letters = 'abcdefghijklmnopqrstuvwxyz'
       >>> rotate(letters, 1)
       'zabcdefghijklmnopqrstuvwxy'
       >>> rotate(letters, -1)
       'bcdefghijklmnopqrstuvwxyza'
       >>> # avec une liste:
       >>> z = list(letters)
       >>> rotate(z, 1)
       ['z', '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 = tuple(letters)
       >>> rotate(z, 1)
       ('z', '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')
    Construire la table de correspondance entre l'entrée et la sortie passera par un dict:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       >>> table = dict(zip(rotate(letters, 1), letters))
    Pour traduire la chaine lue, en ignorant translate et .maketrans, se réduit à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       >>> translate = lambda s, table : ''.join(table[c] for c in s)
       >>> translate('yzab', table)
       'zabc'
    Avec les .maketrans et .translate montré par mont29:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       >>> tr_table = str.maketrans(table)
       >>> translate = lambda s, tr_table : s.translate(tr_table)
       >>> translate('yzab', tr_table)
       'zabc'
    Faut-il empiler les 3 étapes en une seule ligne?
    Genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       >>> def get_translate(seq, c):
       ...     tr_table = str.maketrans(dict(zip(rotate(seq, c), seq)))
       ...     return lambda s: s.translate(tr_table)
       >>> cypher = get_translate(letters, 1)
       >>> cypher('yzab')
       'zabc'
    Comme dechiffrer se contruira comme chiffrer, je pense que oui:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       >>> decypher = get_translate(letters, -1)
       >>> decypher(cypher('abcd')) == 'abcd'
       True
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Le chiffre de César
    Par Elradriel dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 03/11/2016, 01h29
  2. probleme implémentation code crypto chiffre de césar
    Par hakim lyonnais dans le forum Débuter
    Réponses: 5
    Dernier message: 16/04/2015, 17h04
  3. [Turbo Pascal] Chiffrement par décalage (chiffre de César)
    Par tessafadel10 dans le forum Turbo Pascal
    Réponses: 2
    Dernier message: 14/06/2010, 22h43
  4. Recherche programme qui convertit les chiffres arabes en nb
    Par oli57 dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 15/06/2002, 03h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo