Bonjour, je voudrais avoir de l'aide pour faire deux exercices.
ex1: Modifier la fonction chiffre pour qu'elle renvoie le message chiffré(avec les caractères)
ex2: Ecrire fonction dechiffre qui prend en paramètres le message chiffré et la clé et qui renvoie le message chiffré.
message= "Bonjour, comment allez-vous?"
cle="mystere"
def chiffre(message,key):
c =[]
n = len(message)
m = len(key)
j=0
for i in range(n):
c.append(ord(message[i]) ^ ord(key[j]))
j = (j+1)%m
return c
print(chiffre(message,cle))
là la fonction chiffre renvoi une liste de valeur; il faut que tu trouves comment transformer une liste d'entier en chaine de caractère.
def chiffre(message,key):
c =[]
n = len(message)
m = len(key)
j=0
for i in range(n):
c.append(ord(message[i]) ^ ord(key[j]))
j = (j+1)%m
chn= "".join(c)
return chn
print(chiffre(message,cle))
Mais j'obtient un msg d'erreur:
Traceback (most recent call last):
File "C:\Users\Elève\Desktop\Mes dossiers\NSI-terminale\chap 11 Sécurisation des communications\Afaire1-César.py", line 32, in <module>
print(chiffre(message,cle))
File "C:\Users\Elève\Desktop\Mes dossiers\NSI-terminale\chap 11 Sécurisation des communications\Afaire1-César.py", line 28, in chiffre
chn= "".join(c)
TypeError: sequence item 0: expected str instance, int found
>>>
c est une liste de nombres, or ''.join attend une liste de caractères.
Je ne sais pas précisément quel traitement tu voudrais faire, mais je pense que l'idéal serait d'appliquer chr sur chaque nombre.
chn = ''.join(chr(char) for char in c)
et pense à utiliser des noms de variables plus explicites que c/n/m/chn
c est une liste de nombres, or ''.join attend une liste de caractères. Je ne sais pas précisément quel traitement tu voudrais faire, mais je pense que l'idéal serait d'appliquer chr sur chaque nombre.
chn = ''.join(chr(char) for char in c)
et pense à utiliser des noms de variables plus explicites que c/n/m/chn
§AY▼♥ ▲↨T♣►☺ (ce n'est peut-être pas ce que tu attends mais c'est bien ce que fait le code, tu vas te retrouver avec un code ascii compris entre 0 et 63, donc beaucoup de caractères non imprimables) Si tu t'attendais à des caractères alphanumériques plus classiques, il faut les décaler en leur ajoutant 0x30 (48) ou 0x41 (65) (et encore)
umfred a écrit: > sinon dans la boucle, on pourrait faire chn+=chr(c[i]) (en ayant initialiser chn à '' avant la boucle.
Je pense qu'un str.join reste préférable à une utilisation de += dans une boucle.
Je suis également de cet avis, il est canonique de concaténer une itération de chaines avec ''.join, en outre le code est plus court et plus rapide à l'exécution :
from time import perf_counter
from random import choices
N=5*10**6
A=choices(range(1000, 10000), k=N)
# ---------------------------- join ----------------------------
begin_perf = perf_counter()
s1=''.join(str(a) for a in A)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- s+=truc ----------------------------
begin_perf = perf_counter()
s2=''
for a in A:
s2+=str(a)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- Check ----------------------------
print(s1==s2)
Temps d'exécution : 0.92s
Temps d'exécution : 1.32s
True
Toutefois, il existe un code beaucoup plus rapide que ''.join, je vous laisse chercher
PascalOrtiz a écrit:
> Toutefois, il existe un code beaucoup plus rapide que ''.join, je vous laisse chercher
Utiliser une grande chaîne de formatage et un appel à format avec toutes les données du tableau en argument ?
J'ai testé mais j'ai l'impression que c'est plus rapide que join uniquement dans le cas où l'on doit faire les conversions en chaînes de caractères.
Si l'on cherche à concaténer un ensemble de chaînes, join reste donc au-dessus.
Mais peut-être que tu pensais à une autre méthode encore ?
Ce que je disais c'est que dans l'histoire c'est la conversion en chaînes qui est lente. Si tu remplaces A = choices(range(1000, 10000), k=N) par A = [str(a) for a choices(range(1000, 10000), k=N)] et que tu retires tous les appels à str (donc que tu ne testes que la concaténation et non la conversion), tu obtiens des résultats sensiblement différents.
Voici ce que j'obtiens par exemple :
Temps d'exécution : 0.32s
Temps d'exécution : 0.73s
Temps d'exécution : 0.38s
True
En comparaison, j'obtiens à peu près la même chose que toi si je ne fais pas ces conversions en amont.
Temps d'exécution : 1.06s
Temps d'exécution : 1.54s
Temps d'exécution : 0.44s
True
D'ailleurs on peut remarquer que l'on gagne aussi du temps si l'on convertit les chaînes à l'aide d'un appel à la fonction format plutôt qu'à str.
Ce que je disais c'est que dans l'histoire c'est la conversion en chaînes qui est lente. Si tu remplaces A = choices(range(1000, 10000), k=N) par A = [str(a) for a choices(range(1000, 10000), k=N)] et que tu retires tous les appels à str (donc que tu ne testes que la concaténation et non la conversion), tu obtiens des résultats sensiblement différents.
Effectivement, bien vu, il y a avait une interférence avec str. J'obtiens même des écarts plus importants que toi :
from time import perf_counter
from random import choices
N=5*10**6
A=choices(range(1000, 10000), k=N)
B=[str(a) for a in iter(A)]
# ---------------------------- join ----------------------------
begin_perf = perf_counter()
s1=''.join(B)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- s+=truc ----------------------------
begin_perf = perf_counter()
s2=''
for b in B:
s2+=b
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- format ----------------------------
begin_perf = perf_counter()
s3=("{}"*N).format(*B)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- Check ----------------------------
print(s1==s2==s3)
Temps d'exécution : 0.05s
Temps d'exécution : 0.60s
Temps d'exécution : 0.22s
True
entwanne a écrit:
D'ailleurs on peut remarquer que l'on gagne aussi du temps si l'on convertit les chaînes à l'aide d'un appel à la fonction format plutôt qu'à str.
Absolument, et c'est bon à savoir !
EDIT
Si on choisit le formatage classique (à la C), et donc un tuple au lieu d'une liste, le temps de join devient assez proche :
from time import perf_counter
from random import choices
N=5*10**6
A=choices(range(1000, 10000), k=N)
B=tuple(str(a) for a in iter(A))
# ---------------------------- join ----------------------------
begin_perf = perf_counter()
s1=''.join(B)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- s+=truc ----------------------------
begin_perf = perf_counter()
s2=''
for b in B:
s2+=b
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- format ----------------------------
begin_perf = perf_counter()
s3=("{}"*N).format(*B)
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- format ----------------------------
begin_perf = perf_counter()
s4=("%s"*N) %B
delta = perf_counter() - begin_perf
print(f"Temps d'exécution : {delta:.2f}s")
# ---------------------------- Check ----------------------------
print(s1==s2==s3==s4)
Temps d'exécution : 0.05s
Temps d'exécution : 0.57s
Temps d'exécution : 0.14s
Temps d'exécution : 0.08s
True
- Edité par PascalOrtiz 25 février 2021 à 19:45:44
pour la question2:Ecrire fonction dechiffre qui prend en paramètres le message chiffré et la clé et qui renvoie le message chiffré.
J'ai fais ça mais ça ne marche absolument pas, il n'y a même pas de message d'erreur du coup je ne suis pas capable de comprendre l'erreur.
def dechiffrer(key):
messagechiffre= chiffre(message,key)
liste =[]
n = len(messagechiffre)
m = len(key)
j=0
for i in range(n):
liste.append(ord(messagechiffre[i]) ^ ord(key[j]))
j = (j+1)%m
return ''.join(chr(char) for char in liste)
D'abord, comme tu l'as souligné en sous-titre, c'est symétrique. Tu peux utiliser la même fonction pour chiffrer et déchiffrer. Voici de quoi pourrait avoir l'air cette fonction: k=len(key) liste=[] j=0 for c in message: liste.append(ord(c)^ord(key[j])) j=(j+1)%k return ''.join(chr(c) for c in liste) Tu devrais pouvoir faire ceci: m0="bonjour, comment vas-tu?" key="mystere" m1=crypter(m0,key) m2=crypter(m1,key) if m0==m2: print("OK") Comme on te l'a mentionné, la forme chiffrée risque de contenir des caractères non-imprimables.
Le Tout est souvent plus grand que la somme de ses parties.
pour la question2:Ecrire fonction dechiffre qui prend en paramètres le message chiffré et la clé et qui renvoie le message chiffré.
J'ai fais ça mais ça ne marche absolument pas, il n'y a même pas de message d'erreur du coup je ne suis pas capable de comprendre l'erreur.
def dechiffrer(key):
messagechiffre= chiffre(message,key)
liste =[]
n = len(messagechiffre)
m = len(key)
j=0
for i in range(n):
liste.append(ord(messagechiffre[i]) ^ ord(key[j]))
j = (j+1)%m
return ''.join(chr(char) for char in liste)
- Edité par m&m'ss il y a environ 20 heures
Reprends ton énoncé pour commencer: une fonction avec 2 paramètres, le message et la clé
ensuite, normalement, si tu appelles chiffre() avec messagecrypte et cle, ça devrait te redonner le message d'origine.
pour la question2:Ecrire fonction dechiffre qui prend en paramètres le message chiffré et la clé et qui renvoie le message chiffré.
J'ai fais ça mais ça ne marche absolument pas, il n'y a même pas de message d'erreur du coup je ne suis pas capable de comprendre l'erreur.
def dechiffrer(key):
messagechiffre= chiffre(message,key)
liste =[]
n = len(messagechiffre)
m = len(key)
j=0
for i in range(n):
liste.append(ord(messagechiffre[i]) ^ ord(key[j]))
j = (j+1)%m
return ''.join(chr(char) for char in liste)
- Edité par m&m'ss il y a environ 20 heures
Reprends ton énoncé pour commencer: une fonction avec 2 paramètres, le message et la clé
ensuite, normalement, si tu appelles chiffre() avec messagecrypte et cle, ça devrait te redonner le message d'origine.
× 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.
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
Découverte Python Doc Tkinter Les chaînes de caractères
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
Découverte Python Doc Tkinter Les chaînes de caractères
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
Découverte Python Doc Tkinter Les chaînes de caractères
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.