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

Calcul scientifique Python Discussion :

Opérations sur entiers


Sujet :

Calcul scientifique Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut Opérations sur entiers
    Bonjour,

    En voulant apprendre le python, je me suis mis à la cryptographie. J'ai donc fait un petit script pour chiffrer des fichiers texte. Or, j'ai un problème mathématique.

    Pour donner le contexte, le programme fonctionne comme suit:
    1) On charge le fichier;
    2) On extrait un à un les caractères, puis on les met dans une liste;
    3) Pour chaque caractère de la liste, on regarde quel est son rang dans l'alphabet (une autre liste prédéfinie), puis on sauvegarde ce nombre dans une nouvelle liste;
    4) Pour chaque nombre de cette liste nouvellement créée (avec les nombres), on effectue une opération dessus puis on sauvegarde le résultat dans une nouvelle liste (encore une!);
    5) On convertit ce nombre en caractère, puis avec tous les caractères encodés on crée le message codé (chaîne de caractères), mais peu importe.

    Opérations similaires mais inversées pour décoder.

    À l'étape 4, un problème survient (du moins je crois).
    L'idée est de prendre tous les nombres d'une liste, de leur faire subir une transformation (ici une fonction), puis d'enregistrer les résultats:
    Voici le code correspondant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def encoding_calculus(liste, n, s): #une liste, un nombre, un autre nombre (entiers)
    	chaine_code = []
    	for i in range(0, n):
    		k = (int(decimal.Decimal(i**3+i**2-13*i-11+liste[i])))%s
    		chaine_code.append(k)
    	return chaine_code
    Et pour décoder:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def decoding_calculus(liste, n, s): #pareil
    	chaine_decode = []
    	for i in range(0, n):
    		k = (int(decimal.Decimal(-i**3-i**2+13*i+11+liste[i])))%s
    		chaine_decode.append(k)
    	return chaine_decode
    Le problème est qu'après encodage et décodage, certains caractères ne sont pas les mêmes (certains: ponctuellement, je dirais que 97% d'entre eux sont bien les mêmes dans le texte original et après encodage, puis décodage).
    Je suis sûr que l'erreur vient des 2 fonctions ci-dessus. La fonction d'encodage est en fait un polynôme de degré 3 à coefficients entiers. Et je ne comprends pas d'où vient l'erreur. J'ai essayé de contrer les erreurs d'arrondi dûes au binaire (avec decimal), rien n'y fait. Lorsque je passe la fonction en afine (autrement dit (k=a+liste[i])%s ), tout marche.
    Pourquoi ça ne marche pas ???
    Je suis à court d'idées. Quelqu'un aurait la solution ?
    C'est là où j'en viens au bibliothèques mathématiques: dois-je en utiliser une ??
    Merci d'avance

    PS: Je pourrais donner le script entier (qui n'est pas non plus très long), pour plus de détails, mais je ne pense pas que ce soit utile. Si ça vous intéresse, dites-le moi, ou si plus de détails sont necéssaires.

  2. #2
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    perso je vois pas où ça coince, si on considère les valeurs de 0 à 255 (inclues) avec comme modulo 256 on obtient bien la même chose après chiffrement/déchiffrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> decoding_calculus(encoding_calculus(range(256), 256, 256), 256, 256) == range(256)
    True
    il faudrait sans doute que tu précises des valeurs spécifiques pour lesquelles ça ne fonctionne pas mais à vue de nez si tu prends un modulo trop petit c'est évident pour des valeurs trop hautes tu ne retomberas pas sur tes pieds

    quelques remarques d'ordre général :
    • range(0,n) c'est pareil que range(n)
    • les deux fonctions sont presque identiques, on pourrait n'avoir qu'une seule fonction avec un paramètre mode par exemple
    • ce n'est pas une "chaine{_code,_decode}" qui est retournée, mais une liste, à l'inverse en paramètre on pourrait aussi bien passer une chaine, qui est aussi un iterable
    • les commentaires du genre #une liste, un nombre, un autre nombre (entiers) ne servent vraiment à rien à moins d'expliquer à quoi correspondent les variables
    • le paramètre n ne sert à rien, il n'est utilisé que pour limiter le nombre d'éléments traités dans la boucle, autant passer en amont une liste plus courte (liste[:n])
    • accessoirement on peut condenser un peu le tout avec une list comprehension


    on pourrait donc avoir quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ENCODE=1
    DECODE=-1
     
    def calculus(mode, liste, s): # le mode(ENCODE ou DECODE), le texte (liste d'entiers), le modulo (entier)
       return [(int(decimal.Decimal(mode * i ** 3 + mode * i**2 - mode * 13*i - mode * 11 + liste[i]))) % s for i in range(len(liste))]
    et son exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> calculus(DECODE, calculus(ENCODE, range(256), 256), 256) == range(256)
    True

  3. #3
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Bonjour,
    Si "i" est bien un entier positif, je ne vois aucun intérêt à utiliser les opérations sur des décimaux. Avec de surcroît un calcul sur des entiers, le tout étant converti en décimal pour être immédiatement reconverti en entiers…
    (si ce sont bien des entiers positifs).

    Si "i" est négatif, le calcul sera fait en "float", reconverti en décimal, reconverti en entier… Pfiou…

    Clodion
    PS: pour travailler sur des décimaux, il faut en premier convertir tous les nombres en décimaux et ensuite opérer les calculs.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Bonjour BufferBob, merci pour ta réponse rapide.

    La variable s est en fait la longueur de la liste contenant l'alphabet. Donc, comme tu l'as dit, il est normal et cohérent que ça retombe dans l'ensemble du modulo (Z/nZ pour les intimes). Là n'est pas le problème.
    Pour exemple, dans un message, un "j" se transforme en "9" après encodage et décodage, alors qu'il devrait naturellement redevenir un j. Ce "j" est à la 151ème position du message. Il correspond au caractère n°29 dans l'alphabet que voilà:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alphabet = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', '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', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '-', '–', ' ', '\n', '’', '\t', '²']
    Donc C=P+K (mod n): K est l'image du rang du caractère dans le message par la fonction, C est simplement le rang du caractère dans l'alphabet.
    Soit: 29+151^3+151^2-13*151-11 (mod n) = 3 463 807 (mod 126) = 67 (car len(alphabet)=126)

    Ce qui s'encode par un "F" majuscule (car alphabet[67] = "F"). Or, à la 151ème position du message chiffré, je ne vois pas de F. (ni aux alentours).

    En même temps que je fais cette vérification, je me rend compte que les grandeurs utilisées deviennent assez importantes. Et je me demande si Python gère bien ça.

    Dois-je faire appel à une bibliothèque mathématique pour résoudre ce problème ? Car vraiment je ne vois pas ce qui ne va pas, à mon avis ce sont des erreurs de calcul ou d'arrondi en interne, mon programme est hors de cause.
    Le code complet:cryptage - Copie.py

  5. #5
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Romuald-25 Voir le message
    En même temps que je fais cette vérification, je me rend compte que les grandeurs utilisées deviennent assez importantes. Et je me demande si Python gère bien ça.

    Dois-je faire appel à une bibliothèque mathématique pour résoudre ce problème ? Car vraiment je ne vois pas ce qui ne va pas, à mon avis ce sont des erreurs de calcul ou d'arrondi en interne, mon programme est hors de cause.
    Le code complet:cryptage - Copie.py
    Bonjour,
    Ces valeurs très importantes ne posent pas de problème pour les entiers!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> 13**151
    1604893426900600869122943058339200074042717538173708563561768727328532111168979152929302751034763042774648202612459872374195131739043860481933461034923690640920832323237
    >>>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> 13**500
    93686314224509396320290074675123359856766350530320244554512736764286909526960642026267280560384131989923251485550386073014085542980655985141065810944820018278616278352970031368488765490901249747517822536664007345499222275007085960573246526373900412353062505405542861271222819935493894096751288500935261781853442452675933697756069301000595854116340368240227848831493036979873365670959683007770003014495666404281667862235406919716683139776654431695110185492317544845659697001899576964260739908067276770212831311359812603584288431713893323053369311809217970001
    >>>
    La seule limite de taille pour les entiers est la Ram! Et les opération sont exactes!

    Clodion
    PS: sinon, les "print" (voire utilisé avec des conditions) sont souvent très utiles au débogage. IDLE peut fonctionner au pas-à-pas pour comprendre ce qu'il en est.

  6. #6
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    hmm... c'est pas courant de chiffrer/déchiffrer sur des caractères tout en tenant compte des caractères étendus (utf-8 et cie.), en général soit on va avoir un chiffrement en mode texte sur un alphabet simple (éventuellement tout en majuscule) soit on va plutôt travailler sur les octets directement, au flairomètre j'aurai tendance à chercher par là à mon avis, à vérifier.

  7. #7
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 604
    Points : 2 070
    Points
    2 070
    Par défaut
    Je penche plutôt pour un pb de modulo : je suis quasi certain qu'au décodage, tu ne retrouves pas le bon terme car ce n'est pas un bijection.
    Il faudrait faire tourner le pb à la main.
    Essaie de faire tourner le programme ci-joint.
    J'avais fait cela il y a un moment et j'étais tombé sur le même type d'os.
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    def soml(l1,l2):
        return [l1[i]+l2[i] for i in range(len(l1))]
     
    def scal(l,q):
        return [q*l[i] for i in range(len(l))]
     
    def bezout(a,b):
        la = [1,0,a]
        lb = [0,1,b]
        rem = b
        while rem != 0:
            q = la[2]//rem
            lr = soml(la,scal(lb,-q))
            la = lb
            lb = lr
            rem = lb[2]
        return la
     
    def inv_mod(p,n):
        b = bezout(p,n)
        if b[2] == 1:
            return b[0]%n
        else:
            raise ZeroDivisionError
     
    def code(texte):
        return [ord(texte[i]) - 65 for i in range(len(texte))]
     
    def encode(texte):
        mot = ''
        for i in range (len(texte)):
            mot += chr(texte[i]+65)
        return mot
     
    def code_affine(texte,a,b):
        m = code(texte)
        c = [(a*m[i]+b)%26 for i in range(len(m))]
        return encode(c)
     
    def decode_affine(texte,a,b):
        c = code(texte)
        inv_a = inv_mod(a,26)
        d = [(inv_a*(c[i] - b))%26 for i in range(len(c))]
        return encode(d)
     
    message1="ABCDEFGHIJKLMNOPQRSTUVWYZ"
    print(message1)
    print(code_affine(message1,3,5))
    print(decode_affine(code_affine(message1,3,5),3,5))
     
    def cesar_affine_code(texte,m=3,p=5):
        message_code=''
        for lettre in texte:
            u = ord(lettre) - 65
            v = m*u+p
            w= v%26
            t = chr(w+65)
            message_code = message_code + t
            print("lettre : ", lettre, ";\t u : ", u, ";\t v : ", v, ";\t w : ", w, ";\t t : ", t)
        return(message_code)
     
    message1="ABCDEFGHIJKLMNOPQRSTUVWYZ"
    message_code1 = cesar_affine_code(message1,3,5)
    print(message_code1)
    Pas d'aide par mp.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    hmm... c'est pas courant de chiffrer/déchiffrer sur des caractères tout en tenant compte des caractères étendus (utf-8 et cie.), en général soit on va avoir un chiffrement en mode texte sur un alphabet simple (éventuellement tout en majuscule) soit on va plutôt travailler sur les octets directement, au flairomètre j'aurai tendance à chercher par là à mon avis, à vérifier.
    Ces valeurs très importantes ne posent pas de problème pour les entiers!
    Vous avez tous les 2 raison (de mon expérience en crypto).

    Sache BufferBob qu'à la base, mon alphabet était simplement un "string.ascii_uppercase", mais j'ai voulu l'étendre car les majuscules sont contraignantes (moins de caractères, forcément, et il faut formatter le texte ce qui est pénible.)

    Si les entiers ne posent pas de problème (c'est ce que je me suis dit), c'est qu'il saute des caractères de temps en temps dans la lecture de l'alphabet. Mais seulement de temps en temps, car dans la plupart des cas tout s'encode et se décode bien. Dans ce cas c'est python.

    Je ne vois donc qu'une solution: convertir par exemple le texte en binaire, ou en décimal tout simplement, c'est ce que j'essaie de faire avec mes bidouillages de listes mais apparemment cette méthode n'est pas infaillible.

    Pourtant, je rapelle quand-même qu'avec un chiffre de césar (ajout d'un entier constant), sans puissances, tout va très bien...

    Mystère...

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Je penche plutôt pour un pb de modulo : je suis quasi certain qu'au décodage, tu ne retrouves pas le bon terme car ce n'est pas un bijection.
    Il faudrait faire tourner le pb à la main.
    Essaie de faire tourner le programme ci-joint.
    J'avais fait cela il y a un moment et j'étais tombé sur le même type d'os.
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    def soml(l1,l2):
        return [l1[i]+l2[i] for i in range(len(l1))]
     
    def scal(l,q):
        return [q*l[i] for i in range(len(l))]
     
    def bezout(a,b):
        la = [1,0,a]
        lb = [0,1,b]
        rem = b
        while rem != 0:
            q = la[2]//rem
            lr = soml(la,scal(lb,-q))
            la = lb
            lb = lr
            rem = lb[2]
        return la
     
    def inv_mod(p,n):
        b = bezout(p,n)
        if b[2] == 1:
            return b[0]%n
        else:
            raise ZeroDivisionError
     
    def code(texte):
        return [ord(texte[i]) - 65 for i in range(len(texte))]
     
    def encode(texte):
        mot = ''
        for i in range (len(texte)):
            mot += chr(texte[i]+65)
        return mot
     
    def code_affine(texte,a,b):
        m = code(texte)
        c = [(a*m[i]+b)%26 for i in range(len(m))]
        return encode(c)
     
    def decode_affine(texte,a,b):
        c = code(texte)
        inv_a = inv_mod(a,26)
        d = [(inv_a*(c[i] - b))%26 for i in range(len(c))]
        return encode(d)
     
    message1="ABCDEFGHIJKLMNOPQRSTUVWYZ"
    print(message1)
    print(code_affine(message1,3,5))
    print(decode_affine(code_affine(message1,3,5),3,5))
     
    def cesar_affine_code(texte,m=3,p=5):
        message_code=''
        for lettre in texte:
            u = ord(lettre) - 65
            v = m*u+p
            w= v%26
            t = chr(w+65)
            message_code = message_code + t
            print("lettre : ", lettre, ";\t u : ", u, ";\t v : ", v, ";\t w : ", w, ";\t t : ", t)
        return(message_code)
     
    message1="ABCDEFGHIJKLMNOPQRSTUVWYZ"
    message_code1 = cesar_affine_code(message1,3,5)
    print(message_code1)
    Ah si, c'est une bijection et j'en suis sûr. Sinon comment expliques-tu que la plupart du message soir encodé et décodé correctement ?
    Il n'y a vraiment que quelques caractères qui sautent.

  10. #10
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    j'ai regardé vite fait ton code, tu ouvres le fichier+read directement des octets, sans garantir que ça vient de là (pas testé) tu devrais essayer d'ouvrir le fichier directement en utf-8 via codecs.open(fichier, 'r', 'utf-8') et encode/decode avant de chercher les caractères dans la table

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    j'ai regardé vite fait ton code, tu ouvres le fichier+read directement des octets, sans garantir que ça vient de là (pas testé) tu devrais essayer d'ouvrir le fichier directement en utf-8 via codecs.open(fichier, 'r', 'utf-8') et encode/decode avant de chercher les caractères dans la table
    D'accord, merci pour l'astuce, je vais essayer.

  12. #12
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 604
    Points : 2 070
    Points
    2 070
    Par défaut
    Citation Envoyé par Romuald-25 Voir le message
    Ah si, c'est une bijection et j'en suis sûr. Sinon comment expliques-tu que la plupart du message soir encodé et décodé correctement ?
    Il n'y a vraiment que quelques caractères qui sautent.
    Peut-être justement à cause du modulo ?
    Pas d'aide par mp.

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Peut-être justement à cause du modulo ?
    J'y avais pensé. Parce qu'effectivement, il y a des virgules flottantes dans la fonction modulo.

    Mais même en remplaçant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def encoding_calculus(liste, n, s):
    	chaine_code = []
    	for i in range(0, n):
    		r = (i**3+i**2-13*i-11+liste[i])
    		k = r-decimal.Decimal(int(math.floor(r/s)))*s
    		chaine_code.append(k)
    	return chaine_code
    Le problème persiste.
    C'est vraiment étrange, je commence à plus rien y comprendre. J'ai à peu près tout essayé. Ou alors j'ai loupé un truc.

  14. #14
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Bonjour,
    Ce qui laisse penser à un problème avec le modulo est le fait que les "problèmes" semblent tous codé (première étape: "encoding_calculus") en 119 après le modulo (essais pour a, i et h) et sont traduites respectivement en ("}", "5" et "6")…

    PS: Non, non et non! Il n'y a pas de virgules flottantes dans les modulos! Ce sont des entiers, uniquement puisque le toutes les opérations sont constituées d'entiers!

    Clodion

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Je suis désolé mais dans presque tous les langages de programmation, la fonction modulo est
    a (mod b) = a - floor(a/b) * b
    Et là il y a des virgules flottantes, mêmes si elles sont sous-entendues ou invisibles.
    Mais sinon merci bien je sais que les modulos sont sur des entiers.
    À savoir que c'est cette fonction qui s'exécute lorsque python lit "%".

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Non en fait je pense que c'est simplement un problème d'encodage, car selon que j'encode en UTF8, ANSI, etc, ça ne marche pas toujours. (je veux dire que le programme s'arrête carrément, et me réclame des caractères que je n'ai même pas écrits).
    Dans ce cas, je devrais d'abord convertir en décimal mon texte. Mais je ne sais pas vraiment comment faire.

    BufferBob, je n'ai pas bien compris comment fonctionne ton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    codecs.open(fichier, 'r', 'utf-8')
    mais ça m"intéresse. À quoi cela sert-il exactement ? Et comment ça fonctionne ?

  17. #17
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Citation Envoyé par Romuald-25 Voir le message
    Je suis désolé mais dans presque tous les langages de programmation, la fonction modulo est
    a (mod b) = a - floor(a/b) * b
    Et là il y a des virgules flottantes, mêmes si elles sont sous-entendues ou invisibles.
    Mais sinon merci bien je sais que les modulos sont sur des entiers.
    À savoir que c'est cette fonction qui s'exécute lorsque python lit "%".
    Bonjour,
    Si vous voulez…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    alphabet = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', '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', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '-', '–', ' ', '\n', '’', '\t', '²']
    dct = {car:pos for pos, car in enumerate(alphabet)}
     
    def cripte(lig):
            # liste des positions des car dans la phrase
            pos = [dct[car] for car in lig]
            lst = [(i**3+i**2-13*i-11+pos[i])%len(lig) for i in range(len(lig))]
            print("Toutes les valeurs après le modulo:", lst)
     
    with open("plaintext.txt", "r") as fic:
            cripte(fic.readline())
    résultat:
    ============== RESTART: /home/laurent/Bureau/Python/cryptage.py ==============
    Toutes les valeurs après le modulo: [46, 895, 5, 16, 138, 130, 197, 321, 486, 696, 99, 519, 822, 426, 88, 815, 575, 502, 528, 783, 51, 443, 65, 711, 587, 644, 820, 371, 777, 559, 620, 668, 75, 707, 438, 444, 698, 270, 45, 54, 390, 774, 689, 704, 153, 779, 784, 135, 695, 634, 60, 535, 442, 716, 397, 495, 790, 532, 624, 212, 134, 438, 179, 311, 829, 817, 404, 192, 495, 294, 495, 236, 402, 207, 244, 846, 174, 651, 820, 544, 750, 659, 852, 696, 196, 255, 691, 747, 495, 761, 642, 175, 366, 67, 388, 375, 850, 127, 41, 512, 703, 612, 214, 427, 334, 73, 384, 361, 100, 583, 780, 655, 324, 726, 68, 795, 542, 72, 320, 461, 350, 875, 352, 616, 707, 735, 480, 92, 474, 772, 24, 78, 889, 711, 439, 57, 594, 870, 305, 447, 601, 699, 713, 725, 654, 594, 483, 327, 282, 14, 860, 608, 519, 304, 183, 99, 54, 15, 45, 114, 330, 414, 672, 207, 510, 104, 715, 486, 378, 402, 600, 734, 202, 726, 467, 339, 385, 568, 28, 582, 470, 369, 525, 11, 597, 555, 548, 860, 582, 344, 429, 800, 486, 507, 597, 195, 34, 127, 543, 318, 428, 795, 696, 703, 249, 195, 264, 799, 764, 188, 80, 135, 639, 628, 86, 15, 171, 812, 105, 579, 659, 248, 252, 807, 717, 231, 324, 680, 671, 274, 313, 855, 186, 732, 46, 744, 198, 161, 628, 754, 510, 879, 735, 328, 476, 375, 657, 727, 582, 833, 849, 617, 39, 110, 785, 395, 430, 322, 32, 199, 257, 35, 465, 718, 737, 519, 117, 402, 582, 392, 113, 557, 825, 24, 869, 708, 270, 680, 41, 159, 270, 75, 757, 399, 887, 359, 640, 51, 138, 156, 156, 100, 875, 696, 526, 375, 49, 644, 342, 27, 603, 318, 76, 707, 369, 195, 793, 600, 582, 404, 384, 430, 626, 702, 64, 434, 54, 480, 243, 94, 47, 135, 375, 807, 278, 23, 806, 850, 260, 663, 229, 48, 186, 317, 717, 459, 413, 564, 43, 743, 585, 852, 313, 102, 162, 495, 168, 144, 393, 123, 879, 272, 735, 726, 107, 708, 727, 215, 28, 303, 721, 819, 185, 896, 318, 878, 0, 510, 502, 879, 818, 250, 206, 463, 269, 527, 383, 675, 551, 866, 774, 270, 238, 807, 774, 475, 744, 442, 882, 803, 343, 475, 366, 670, 597, 284, 534, 531, 68, 227, 129, 610, 792, 735, 438, 630, 597, 321, 698, 792, 691, 347, 726, 723, 581, 236, 572, 791, 648, 404, 842, 248, 360, 303, 116, 735, 119, 367, 501, 563, 309, 54, 575, 123, 448, 644, 814, 855, 845, 754, 609, 479, 112, 727, 458, 870, 460, 50, 582, 26, 464, 18, 466, 20, 492, 113, 630, 330, 132, 716, 548, 423, 378, 411, 529, 704, 113, 487, 101, 783, 510, 435, 526, 727, 137, 646, 394, 371, 328, 574, 170, 678, 529, 605, 889, 451, 344, 260, 478, 62, 840, 795, 162, 725, 627, 788, 325, 142, 221, 625, 406, 518, 96, 743, 842, 414, 295, 507, 210, 283, 680, 456, 635, 316, 364, 15, 749, 187, 57, 287, 46, 250, 876, 207, 687, 844, 537, 689, 401, 663, 341, 570, 486, 704, 623, 159, 214, 747, 53, 761, 290, 183, 726, 23, 771, 293, 384, 120, 493, 543, 340, 699, 682, 480, 777, 16, 754, 329, 528, 522, 330, 622, 773, 725, 431, 834, 204, 86, 778, 483, 695, 835, 825, 626, 252, 646, 893, 171, 21, 774, 474, 69, 433, 726, 78, 74, 57, 862, 702, 543, 156, 668, 284, 807, 217, 564, 114, 350, 653, 27, 330, 595, 96, 296, 659, 114, 503, 15, 582, 92, 675, 408, 242, 127, 65, 134, 354, 487, 843, 483, 43, 752, 666, 711, 891, 354, 24, 591, 495, 584, 840, 459, 79, 20, 138, 465, 90, 51, 48, 352, 11, 798, 20, 403, 179, 193, 483, 231, 83, 327, 869, 809, 165, 807, 701, 116, 834, 830, 329, 221, 434, 115, 195, 707, 538, 812, 613, 788, 507, 587, 219, 236, 702, 726, 328, 335, 724, 692, 251, 280, 791, 855, 636, 702, 467, 766, 663, 251, 191, 739, 59, 879, 255, 318, 19, 272, 210, 750, 132, 803, 398, 583, 475, 185, 438, 331, 880, 320, 391, 303, 715, 32, 36, 711, 261, 534, 654, 387, 51, 403, 650, 548, 352, 107, 414, 653, 720, 681, 486, 159, 638, 159, 283, 402, 432, 375, 190, 872, 550, 243, 585, 75, 516, 700, 71, 285, 468, 624, 801, 123, 149, 324, 442, 600, 888, 90, 330, 630, 132, 423, 834, 439, 94, 703, 537, 515, 423, 487, 782, 108, 496, 150, 801, 696, 759, 55, 474, 862, 732, 579, 679, 80, 555, 311, 274, 476, 862, 570, 582, 653, 144, 788, 775, 111, 621, 486, 633, 231, 827, 96, 406, 226, 292, 717, 554, 704, 273, 215, 500, 199, 299, 819, 619, 20, 678, 825, 450, 591, 95, 872, 359, 259, 656, 443, 702, 554, 835, 667, 110, 36, 339, 359, 721, 720, 338, 459, 187, 470, 432, 732, 801, 474, 816, 666, 178, 288, 82, 435, 478, 242, 660, 673, 362, 716, 809, 614, 234, 306, 228, 3, 212, 419, 186, 711, 127, 224, 108, 704, 193, 402, 500, 255, 819, 328, 566, 735, 567, 374, 21, 480, 791, 55, 236, 118, 899, 665, 341, 869, 395, 843, 136, 390, 666, 687, 796, 859, 896, 106, 112, 124]
    Texte initial:
    Dell Comics est une filiale de la maison d'édition Dell Publishing fondée en 1921 par George T. Delacorte, Jr. Dès 1929, Dell Publishing s'intéresse à l'édition de bandes dessinées mais il faut attendre en 1936 pour qu'elle se lance vraiment sur ce marché en expansion lorsqu'elle publie Popular Comics. À la fin des années 1930, la maison d'édition s'associe à la Western Publishing et à The Walt Disney Company pour publier des adaptations et des histoires originales mettant en scène les personnages Disney. Elle devient alors un éditeur important. D'autres héros de dessins animés sont par la suite aussi adaptés en comics tout comme plusieurs films ou séries télévisées. Jusque dans les années 1950, Dell Comics est le premier éditeur de comics avec des titres se vendant à plusieurs millions d'exemplaires comme Walt Disney's Comics and Stories (plus de 3 millions pour chaque numéro en 1953).
    Je suis curieux de savoir ou se planque un type "float".
    Et donc le besoin des fonction "int" et "decimal". S'il y a véritablement un problème avec le modulo, alors c'est sur la liste des bugs Python3 qu'il faut intervenir!
    Personnellement j'en doute, mais rien n'est impossible.

    Clodion

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Clodion Voir le message

    Je suis curieux de savoir ou se planque un type "float".

    Clodion
    Je suppose qu'il est dans le fichier de la bibliothèque math, tout simplement (à vrai dire, je n'ai pas vérifié, mais j'en suis presque sûr, cela dit je peux me tromper). Car, comme je l'ai dit, les langages de programmation utilisent la fonction partie entière pour calculer un modulo (voir la définition). Dans le cas contraire, je suis curieux de voir quel procédé utilise python pour touver le reste de la division de 2 entiers a et b.
    Cependant, vous avez raison, il n'y a pas de float directement dans le programme.

    Merci pour le code.

  19. #19
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 604
    Points : 2 070
    Points
    2 070
    Par défaut
    Avez-vous fait tourner le programme que je vous ai fourni ?
    On voit le pb de modulo et de certains caractères correctement décodés, d'autres non.
    Pas d'aide par mp.

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Et quelles sont les conclusions, je veux dire les causes de ces caractères récalcitrants ?
    Avez-vous pu en trouver ?

Discussions similaires

  1. Opération sur des entiers codés dans un tableau
    Par Nurza dans le forum Langage
    Réponses: 7
    Dernier message: 28/09/2012, 13h57
  2. [TPW] Calculatrice effectuant des opérations sur les entiers longs
    Par forum dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 04/12/2011, 12h36
  3. Caml win/ opérations sur des séquences d'entiers
    Par Sophie_26 dans le forum Caml
    Réponses: 29
    Dernier message: 02/05/2007, 21h25
  4. Opération sur de grands entiers
    Par tutu dans le forum C
    Réponses: 16
    Dernier message: 24/05/2005, 09h56
  5. opérations sur les dates
    Par coucoucmoi dans le forum Débuter
    Réponses: 2
    Dernier message: 12/08/2003, 12h45

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