Partage
  • Partager sur Facebook
  • Partager sur Twitter

Chiffre de césar

distance à 'a'

    15 octobre 2021 à 22:44:20

    Bonjour à tous

    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' ?

    chr(((ord('z') + 2) - ord('a')) % 26 + ord('a'))

    Merci pour votre aide

    • Partager sur Facebook
    • Partager sur Twitter
      16 octobre 2021 à 2:37:35

      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'
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        16 octobre 2021 à 10:00:23

        dussinguillaume a écrit:

        (ord('z') + 2) - ord('a')

        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

        • Partager sur Facebook
        • Partager sur Twitter
          16 octobre 2021 à 11:56:08

          dussinguillaume a écrit:

          Et pourquoi ensuite ré-ajouter la valeur ASCII de 'a' ?

          Parce que la valeur ASCII de 'a' n'est pas 0.

          On pourrait écrire:

          >>> alphabet = 'abcdefghijklmnopqrstuvwxyz'
          >>> alphabet.index('a')
          0
          >>> alphabet.index('z')
          25
          >>> alphabet[(alphabet.index('z') + 2) % 26]
          'b'
          >>>

          alphabet.index remplaçant ord...

          • Partager sur Facebook
          • Partager sur Twitter
            16 octobre 2021 à 22:12:46

            mps a écrit:

            >>> alphabet = 'abcdefghijklmnopqrstuvwxyz'
            >>> alphabet.index('a')
            0
            >>> alphabet.index('z')
            25
            >>> alphabet[(alphabet.index('z') + 2) % 26]
            'b'
            >>>

            alphabet.index remplaçant ord...


            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 :

            def cesar(w, decal):
                return ''.join(map(lambda c:chr(ord("a")+(ord(c)+decal-ord("a"))%26), w))
            
            def make_cesar(decal):
                from string import ascii_lowercase as alpha
                alpha_decal=alpha[decal:]+alpha[:decal]
                return str.maketrans(alpha, alpha_decal)
            
            w="python"
            decal=3
            trans=make_cesar(decal)
            
            print(w.translate(trans))
            print(cesar(w, decal))
            mvqelk
            mvqelk
            




            • Partager sur Facebook
            • Partager sur Twitter
              17 octobre 2021 à 18:57:02

              Merci pour tous ces retour.

              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

              • Partager sur Facebook
              • Partager sur Twitter

              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.
              • Editeur
              • Markdown