Merci pour toutes vos réponses, j'avoue que je débute en programmation. J'ai lu tout vos messages mais je dois avouer que je n'ai pas compris la moitié de vos proposition... Dans le projet que je dois réaliser, une fois que j'ai vérifié si il y avait tout les caractères demandé, je doit afficher une image à coté de chaque bouton "majuscules", "minuscules"... et insérer une image avec un icone tel que "✅" ou "❌" que j'ai sur mon pc en jpg. Et à la fin je dois en plus rajouter une phrase pour qui dira si le mot de passe est conforme ou pas. Il me semble aussi que je dois tout mettre dans la même fonction pour ensuite rajouter un bouton qui aurait une commande pour faire ma fonction car je suis sur une fenêtre tkinter.
J'ai repris quelque idée dont vous avez parlez et fait des recherches et voici le code que j'ai fait pour l'instant mais il ne marche pas complètement non plus. Il m'écrit toujours la même chose qu'importe le mot de passe entré.
def verification():
mdp_entree = 'nffkr#fdgDFEF'
majuscules = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
minuscules = 'abcdefghijklmnopqrstuvwxyz'
chiffres = '0123456789'
caracterespe= '!"#$%&\'-./:;<=>?@[\]^_`'
value=0
if any(a in majuscules for a in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(b in minuscules for b in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(c in chiffres for c in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(d in caracterespe for d in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if value ==4:
print("Le mot de passe généré est conforme")
else:
print("Le mot de passe ne comprend pas assez de caractères différents.")
#Bouton pour vérifier le mot de passe
bouton_verifier=Button(ma_fenetre, text="Vérifier", bg='#C3DAE1', command=verification)
bouton_verifier.place(x=650,y=350)
Bonjour, j'ai un projet à réaliser, dans lequel il m'est demandé de créer une application qui va générer un mot de passe aléatoire. Et ensuite de vérifier si ce même mot de passe contient: des majuscules, des minuscules, des chiffres et des caractères spéciaux(j'ai choisi de seulement utiliser: !"#$%&'-./:;<=>?@[\]^_` qui se trouve dans le code ascii entre 33-47 et 58-64 et 91-96). Mais je bloque pour cette deuxième partie j'ai commencé un code mais il ne marche absolument pas et je n'ai plus aucune idée... Si on pouvait me venir en aide ce serait super! Voici mon début de code:
def verificateur():
mdp_entree = 'I#MTB%Z?'
for i in (65, 91):
maj=(mdp_entree.find(chr(i)))
if maj == -1:
print("Le mot de passe ne contient pas de majuscules")
else:
print ("✅")
for a in (97, 123):
mini = (mdp_entree.find(chr(a)))
if mini == -1:
print("Le mot de passe ne contient pas de minuscules")
else:
print ("✅")
for b in (48, 58):
chf=(mdp_entree.find(chr(b)))
if chf == -1:
print("Le mot de passe ne contient pas de chiffres")
else:
print ("✅")
for c in (33, 47 and 58, 65 and 91, 97):
car=(mdp_entree.find(chr(c)))
if car == -1:
print("Le mot de passe ne contient pas de caractères")
else:
print ("✅")
Pourquoi fonctionner avec les codes ASCII et chr() ? for c in mdp: if c not in 'abcdefghijklmnopqrstuvwxyz": print("Le mot de passe ne contient pas de minuscules") Et tu fais la même chose pour les autres ensembles de caractères.
Le Tout est souvent plus grand que la somme de ses parties.
Je ne sais pas gérer le backslash qui est un caractère particulier s'il se trouve en dernière position.
J'ai fait une fonction avec 4 drapeaux concernant les 4 conditions requises pour le mot de passe. Je n'ai fait qu'un seul for "optimisé" pour qu'il arrête de vérifier des conditions déjà valables. En gros, dès que tu as une majuscule, ça ne sert à rien de tester s'il y a une majuscule pour les caractères suivant.
À chaque tour de for, je vérifie si les 4 conditions sont vraies. Je stoppe la boucle si c'est le cas.
et if c not in 'azertyuiopmlkjhgfdsqwxcvbn' c'est pareil que if not c.islower()
Le comportement de '\' en fin de chaîne semble différent suivant qu'on est en invite de commande ou dans un script. Voici ce que je peux faire dans un script: n="\\" print(n) if n in "abc\\": print("C'est là") \ C'est là
C'est plus subtil que ça: >>> n="abc\\";n;print(n) 'abc\\' abc\
@CristianoRolando: Ça ressemble à ceci? flag_upper = flag_upper or caractere.isupper()
- Edité par PierrotLeFou 23 octobre 2021 à 7:28:40
Le Tout est souvent plus grand que la somme de ses parties.
Je ne sais pas si c'est d'importance ici mais vérifier qu'il y a au moins une minuscule, une majuscule, un chiffre et un caractère spécial n'équivaut pas à vérifier que le mot de passe ne contient que des caractères alphanumériques et le set de caractères spéciaux choisis.
Une regex pour vérifier que le mot de passe respecte les conditions (+ une condition de longueur de minimum 10 caractère et maximum 20) et qui vérifie qu'aucun autre caractère n'est utilisé (j'ai laissé l'espace en tant que caractère spécial, je ne sais pas si c'est voulu):
Ce n'est sans doute pas du niveau que tu souhaiterais, mais voilà une manière de faire,
from string import (
ascii_uppercase,
ascii_lowercase,
)
MAJUSCULES = set(ascii_uppercase)
MINUSCULES = set(ascii_lowercase)
CHIFFRES = set(map(str, range(0, 10)))
def verificateur(mdp_entree):
compteur = {
"majuscules": 0,
"minuscules": 0,
"chiffres": 0,
"caracteres speciaux": 0
}
for lettre in mdp_entree:
if lettre in MAJUSCULES:
compteur["majuscules"] += 1
elif lettre in MINUSCULES:
compteur["minuscules"] += 1
elif lettre in CHIFFRES:
compteur["chiffres"] += 1
else:
compteur["caracteres speciaux"] += 1
return compteur
cpt = verificateur('I#MTB%Z?')
print("Nous avons compté:")
for typ, nombre in cpt.items():
print(f" - {nombre} {typ}")
- Edité par fred1599 23 octobre 2021 à 10:43:23
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
def verificateur():
mdp_entree = 'I#MTB%Z?'
for i in (65, 91):
maj=(mdp_entree.find(chr(i)))
if maj == -1:
print("Le mot de passe ne contient pas de majuscules")
else:
print ("✅")
for a in (97, 123):
mini = (mdp_entree.find(chr(a)))
if mini == -1:
print("Le mot de passe ne contient pas de minuscules")
else:
print ("✅")
for b in (48, 58):
chf=(mdp_entree.find(chr(b)))
if chf == -1:
print("Le mot de passe ne contient pas de chiffres")
else:
print ("✅")
for c in (33, 47 and 58, 65 and 91, 97):
car=(mdp_entree.find(chr(c)))
if car == -1:
print("Le mot de passe ne contient pas de caractères")
else:
print ("✅")
Ton code contient de nombreuses erreurs basiques :
tu confonds (97, 123) et son range
ton code c in (33, 47 and 58, 65 and 91, 97) montre que tu codes en Python comme tu écrirais en français
ton algorithme est à revoir : il faut parcourir plutôt les lettres du mots de passe plutôt que de regarder l'espace de tous les caractères possibles
tu fais des affichages au lieu de placer des informations dans des variables ce qui t'empêche de réaliser l'algorithme correctement
Probablement que tu dois faire un exercice pour lequel tu n'as pas été préparé, c'est très courant sur ce forum.
PierrotLeFou a écrit:
Le comportement de '\' en fin de chaîne semble différent suivant qu'on est en invite de commande ou dans un script.
Je ne pense pas. N'oublie pas que l'affichage sans print dans une console revient à appliquer la fonction standard repr.
CristianoRolando a écrit:
Je ne sais pas gérer le backslash qui est un caractère particulier s'il se trouve en dernière position.
Dans une chaîne littérale, ce n'est pas possible si le backslash n'est pas échappé. Sinon,tu concatènes le chr qui va bien.
CristianoRolando a écrit:
J'ai fait une fonction avec 4 drapeaux concernant les 4 conditions requises pour le mot de passe. Je n'ai fait qu'un seul for "optimisé" pour qu'il arrête de vérifier des conditions déjà valables. En gros, dès que tu as une majuscule, ça ne sert à rien de tester s'il y a une majuscule pour les caractères suivant.
À chaque tour de for, je vérifie si les 4 conditions sont vraies. Je stoppe la boucle si c'est le cas.
Effectivement, c'est ce qu'il faut faire, dans l'idéal. Je pense qu'on en demande pas tant à l'auteur de la question.
fred1599 a écrit:
@multi17,
Ce n'est sans doute pas du niveau que tu souhaiterais, mais voilà une manière de faire,
from string import (
ascii_uppercase,
ascii_lowercase,
)
MAJUSCULES = set(ascii_uppercase)
MINUSCULES = set(ascii_lowercase)
CHIFFRES = set(range(0, 10))
def verificateur(mdp_entree):
compteur = {
"majuscules": 0,
"minuscules": 0,
"chiffres": 0,
"caracteres speciaux": 0
}
for lettre in mdp_entree:
if lettre in MAJUSCULES:
compteur["majuscules"] += 1
elif lettre in MINUSCULES:
compteur["minuscules"] += 1
elif lettre in CHIFFRES:
compteur["chiffres"] += 1
else:
compteur["caracteres speciaux"] += 1
return compteur
cpt = verificateur('I#MTB%Z?')
print("Nous avons compté:")
for typ, nombre in cpt.items():
print(f" - {nombre} {typ}")
Pas compris l'intérêt de compter le nombre de caractères d'un type ou d'un autre pour répondre à la question qui est d'écrire une fonction booléenne is_valid(mdp) et donc qu'il y ait 10 majuscule ou une seule, c'est pareil.
CHIFFRES est une liste de int au lieu de caractères.
Pas compris l'intérêt de compter le nombre de caractères d'un type ou d'un autre pour répondre à la question qui est d'écrire une fonction booléenne is_valid(mdp) et donc qu'il y ait 10 majuscule ou une seule, c'est pareil. CHIFFRES est une liste de int au lieu de caractères.
Je n'ai pas compris cela, de la manière où il écrit son code, on remarque qu'il souhaite afficher la présence ou non de chacun des types de caractères.
Après, même si cela n'est pas la demande, ce genre de fonction est générique et permet donc d'appliquer plusieurs utilisations différentes.
Exact pour CHIFFRES, je modifie.
EDIT: En observant la demande, il pourrait à mon sens utiliser cette fonction en détectant les valeurs valant 0 afin d'en déterminer les absences de types.
- Edité par fred1599 23 octobre 2021 à 10:45:47
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Je n'ai pas compris cela, de la manière où il écrit son code, on remarque qu'il souhaite afficher la présence ou non de chacun des types de caractères.
cf. le titre de son message (vérification).
Une première proposition (non optimale) :
def check(mdp):
isspecial=lambda c: c in "!\"#$%&'-./:;<=>?@[\]^_`"
return (any(map(str.islower, mdp)) and
any(map(str.isupper, mdp)) and
any(map(str.isdigit, mdp)) and
any(map(isspecial, mdp)))
for mdp in["aZ5,4mplO", "aZ5;4mplO"]:
print(mdp, check(mdp))
aZ5,4mplO False
aZ5;4mplO True
- Edité par PascalOrtiz 23 octobre 2021 à 10:56:52
Il y a un truc que j'ai pas compris : pourquoi vérifier un mot de passe crée par votre générateur ?
class PasswordError(ValueError):
pass
def check_password(password, predicats):
"""Vérifie que le mot de passe valide les prédicats.
La fonction lève une exception PasswordError si un prédicat n'est pas
validé, sinon elle renvoie None.
predicats doit être une liste de couples (prédicat et message d'erreur).
password doit être un objet vérifiable par les prédicats.
"""
for predicat, message in predicats:
if not predicat(password):
raise PasswordError(message)
from string import punctuation
predicats = (
((lambda s: len(s) > 7), "Le mot de passe est trop petit."),
((lambda s: any(map(str.islower, s))),
"Le mot de passe ne contient pas de minuscule."),
((lambda s: any(map(str.isupper, s))),
"Le mot de passe ne contient pas de majuscule."),
((lambda s: any(map(str.isdigit, s))),
"Le mot de passe ne contient pas de chiffre."),
((lambda s: any(c in punctuation for c in s)),
"Le mot de passe ne contient pas de caractère spécial.")
)
check_password(input("passwd: "), predicats) or print("Mot de passe Valide !")
@PascalOrtiz, il n'est pas demandé une fonction qui renvoie un booléen mais uniquement une fonction qui vérifie un mot de passe.
@PascalOrtiz, il n'est pas demandé une fonction qui renvoie un booléen mais uniquement une fonction qui vérifie un mot de passe.
Différence ? Vérifier si oui (True) ou non (False) le mot de passe est valide, donc il s'agit bien de créer une fonction booléenne. Sinon, il s'agit de dire pourquoi le mdp est invalide. Dans le fond, ça ne change pas grand chose, ton code de vérification est essentiellement le même que celui que j'ai proposé.
Une vérification lève une erreur quand elle échoue et rien quand elle réussie, la où une appartenance détermine un oui ou non.
Tu veux dire lever une exception ? Ce n'est pas ce que dit explicitement l'énoncé et je doute que ça fasse partie des attendus de l'exercice vu le niveau du code proposé par l'auteur. Dans l'absolu, oui, lever une exception est une réponse possible (tout dépend de la question).
Non vraiment j'insiste, une vérification n'est pas une appartenance ; is_whatever() n'est pas check_whatever(), ni match_whatever(). Ce serait une erreur de réduire cela à un détail parce que ça a une importance sémantique réelle. C'est comparable à confondre condition et assertion., par exemple.
J'ai vérifié le code source de différentes lib dignes de confiance et la sémantique de check_whatever semble relativement bien établie : la plupart du temps, en cas d'échec de la vérification, elle lève une exception.
Toutefois, il y a des exceptions à cette règle, comme, en vrac :
def _check_blas():
# Checks if a BLAS is available so e.g. dot will work
try:
ensure_blas()
except ImportError:
return False
return True
@atexit.register
def _check_teardown():
assert _nest_count == 0, ('_setup_random() and _teardown_random() '
'must be called in pairs.')
def check_token_signature(token: str,
secret_key: Optional[bytes] = settings.secret_key_bytes(),
signed: Optional[bool] = settings.sign_sessions()) -> bool:
"""Check the signature of a token and the contained signature.
The server uses this function to check whether a token and the
contained session id was generated with the correct secret key.
If signed sessions are disabled, this function always returns True.
Args:
token (str) :
The token to check
secret_key (str, optional) :
Secret key (default: value of BOKEH_SECRET_KEY environment variable)
signed (bool, optional) :
Whether to check anything (default: value of BOKEH_SIGN_SESSIONS
environment variable)
Returns:
bool
"""
secret_key = _ensure_bytes(secret_key)
if signed:
token_pieces = token.split('.', 1)
if len(token_pieces) != 2:
return False
base_token = token_pieces[0]
provided_token_signature = token_pieces[1]
expected_token_signature = _signature(base_token, secret_key)
# hmac.compare_digest() uses a string compare algorithm that doesn't
# short-circuit so we don't allow timing analysis
token_valid = hmac.compare_digest(
expected_token_signature, provided_token_signature
)
session_id = get_session_id(token)
session_id_valid = check_session_id_signature(session_id, secret_key, signed)
return token_valid and session_id_valid
return True
def check_bootsec():
buf = bytearray(bdev.SEC_SIZE)
bdev.readblocks(0, buf)
empty = True
for b in buf:
if b != 0xff:
empty = False
break
if empty:
return True
fs_corrupted()
def fs_corrupted():
import time
while 1:
print("""\
The FAT filesystem starting at sector %d with size %d sectors appears to
be corrupted. If you had important data there, you may want to make a flash
snapshot to try to recover it. Otherwise, perform factory reprogramming
of MicroPython firmware (completely erase flash, followed by firmware
programming).
""" % (bdev.START_SEC, bdev.blocks))
time.sleep(3)
Voici ma modeste contribution: def check_pwd(pwd): U = False L = False D = False O = False for c in pwd: U = U or c.isupper() L = L or c.islower() D = D or c.isdigit() O = O or c in "!#\"$%&'-./:;<=>?@[\\]^_`" return U and L and D and O
Le Tout est souvent plus grand que la somme de ses parties.
Voici ma modeste contribution: def check_pwd(pwd): U = False L = False D = False O = False for c in pwd: U = U or c.isupper() L = L or c.islower() D = D or c.isdigit() O = O or c in "!#\"$%&'-./:;<=>?@[\\]^_`" return U and L and D and O
Pas si modeste que ça ! Je viens de réaliser que ton code est en fait plus efficace que d'utiliser any puisque tu parcours la chaîne une fois et une seule et que tu cesses de tester un critère qui a été validé, astucieux le coup du U=U or isupper(). J'avais quelque chose d'analogue mais moins simple :
def is_valid(mdp):
isspecial=lambda c: c in "!\"#$%&'-./:;<=>?@[\]^_`"
cat=set([str.islower, str.isupper, str.isdigit, isspecial])
for c in mdp:
out=False
for f in cat:
if f(c):
out=True
break
if out:
cat.remove(f)
if not cat:
return True
return False
print("-----------------")
for mdp in["aZ5,4mplO", "aZ5;4mplO"]:
print(mdp, is_valid(mdp))
EDIT
avec la nuance, toutefois, que mon code cesse la validation lorsqu'elle est acquise alors que ton code, lui, la poursuit.
- Edité par PascalOrtiz 23 octobre 2021 à 15:30:14
Ho! Tu fais un set de fonctions et tu fais sauter une fonction si elle est utilisée. Dans ton code comme le mien, si on a un caractère non permis, ce n'est pas détecté.
edit:
Correction, ton code le détecte bien
- Edité par PierrotLeFou 23 octobre 2021 à 18:42:06
Le Tout est souvent plus grand que la somme de ses parties.
Merci pour toutes vos réponses, j'avoue que je débute en programmation. J'ai lu tout vos messages mais je dois avouer que je n'ai pas compris la moitié de vos proposition...
Edité par multi17 il y a environ 1 heure
Si tu réponds, il ne faut pas modifier ton message initial mais rajouter un nouveau message dans la discussion.
multi17 a écrit:
Merci pour toutes vos réponses, j'avoue que je débute en programmation. J'ai lu tout vos messages mais je dois avouer que je n'ai pas compris la moitié de vos proposition...
Je m'en doutais un peu ...
multi17 a écrit:
Il me semble aussi que je dois tout mettre dans la même fonction pour ensuite rajouter un bouton qui aurait une commande pour faire ma fonction car je suis sur une fenêtre tkinter.
OK mais là on part dans quelque chose de largement différent. Tu connais Tkinter ?
multi17 a écrit:
J'ai repris quelque idée dont vous avez parlez et fait des recherches et voici le code que j'ai fait pour l'instant mais il ne marche pas complètement non plus. Il m'écrit toujours la même chose qu'importe le mot de passe entré.
def verification():
mdp_entree = 'nffkr#fdgDFEF'
majuscules = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
minuscules = 'abcdefghijklmnopqrstuvwxyz'
chiffres = '0123456789'
caracterespe= '!"#$%&\'-./:;<=>?@[\]^_`'
value=0
if any(a in majuscules for a in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(b in minuscules for b in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(c in chiffres for c in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if any(d in caracterespe for d in mdp_entree):
print ("✅")
value= value + 1
else:
print("❌")
if value ==4:
print("Le mot de passe généré est conforme")
else:
print("Le mot de passe ne comprend pas assez de caractères différents.")
Et ça t'affiche quoi pour que tu dises :
Il m'écrit toujours la même chose qu'importe le mot de passe entré.
Si je veux que tous les caractères soient valides, j'aurais écrit (vu que tu connais any ): U = " lettres majuscules " L = " lettres minuscules " D = " chiffres " S = " caractères spéciaux " if all(c in U+L+D+S for c in pwd): return True # c'est valide return False
Si tu en veux au moins un de chaque groupe: if any(c in U for c in pwd) and any(c in L for c in pwd) and any(c in D for c in pwd) and any(c in S for c in pwd): Pas tout à fait la façon la plus efficace. C'est cependant simple à coder.
- Edité par PierrotLeFou 24 octobre 2021 à 1:08:57
Le Tout est souvent plus grand que la somme de ses parties.
Voici mon code, si vous avez des idées pour l'améliorer avec all ou any. Ils ont l'air sympa ces mots-clés.
def verifier(mot_de_passe):
a_majuscule = False
a_minuscule = False
a_chiffre = False
a_caractere_special = False
for caractere in mot_de_passe:
if not a_majuscule:
if caractere.isupper():
a_majuscule = True
continue
if not a_minuscule:
if caractere.islower():
a_minuscule = True
continue
if not a_chiffre:
if caractere.isdigit():
a_chiffre = True
continue
if not a_caractere_special:
if caractere in "!\"#$%&'-./:;<=>?@[\\]^_`":
a_caractere_special = True
continue
if a_majuscule and a_minuscule and a_chiffre and a_caractere_special:
break
if a_majuscule and a_minuscule and a_chiffre and a_caractere_special:
return True
return False
vrai = verifier("tfeGS-D457")
faux = verifier("fr45GF))")
print(vrai)
print(faux)
print("Les parenthèses ne sont pas dans la liste des caractères spéciaux")
@CristianoRolando: Mon dernier post avec any() le montre, mais ça oblige à parcourir le mot de passe plusieurs fois. À la fin de ta fonction: if a_majuscule and a_minuscule and a_chiffre and a_caractere_special: return True return False Peut être remplacé par: return a_majuscule and a_minuscule and a_chiffre and a_caractere_special Tout comme mon code avec des flags, le tien donne True si un caractère non désiré se trouve dans le mot de passe (essaies "|") Mon code avec all() est correct de ce point de vue.
Mais il ne garantit pas qu'il y a un caractère dans chaque groupe.
Il y a bien ceci, mais c'est assez long également: for c in pwd: if not c.islower() and not c.isupper() and not c.isdigit() and c not in "!#\"$%&'-./:;<=>?@[\\]^_`": return False return True
@PascalOrtiz: Après avoir retesté ton code avec la chaîne "Aa0;|" j'obtiens True cela veut dire que lorsque tous les tests ont été éliminés, tout caractère invalide est accepté.
- Edité par PierrotLeFou 24 octobre 2021 à 4:03:24
Le Tout est souvent plus grand que la somme de ses parties.
def verif(mdp):
res = 0
for c in mdp:
res |= c.islower() or c.isupper()*2 or c.isdecimal()*4 or c.isprintable()*8
if res == 15:
return True
CristianoRolando a écrit:
if c not in 'azertyuiopmlkjhgfdsqwxcvbn' c'est pareil que if not c.islower()
non, les caractères accentués sont lower().
PierrotLeFou a écrit:
Voici ma modeste contribution: def check_pwd(pwd): U = False L = False D = False O = False for c in pwd: U = U or c.isupper() L = L or c.islower() D = D or c.isdigit() O = O or c in "!#\"$%&'-./:;<=>?@[\\]^_`" return U and L and D and O
joli, très joli même ! peut-être en utilisant les walrus on peur éviter de parcourir tout le mot de passe.
@josmiley: Tu dois évaluer toutes les fonctions pour chaque caractère comme je le fais à la fin du dernier post. Ce code est environ 4 fois plus lent que mon code avec des flags. As-tu un indice sur la façon d'utiliser les walrus dans ce contexte? Je ne suis pas convaincu que cela pourrait éviter de parcourir tout le mot de passe. J'ai insisté à quelques reprises sur le fait qu'aucun code ne détecte les caractères invalides. Voici un code qui le fait mais qui est lent lui aussi: def check4(pwd): pw_i = list(pwd) pw_u = (c for c in pw_i if not c.isupper()) if len(pw_u) == len(pw_i): return False pw_l = [c for c in pw_u if not c.islower()] if len(pw_l) == len(pw_u): return False pw_d = [c for c in pw_l if not c.isdigit()] if len(pw_d) == len(pw_l): return False pw_s = [c for c in pw_d if c not in "!#\"$%&'-./:;<=>?@[\\]^_`"] if len(pw_s) == len(pw_d): return False return len(pw_s) == 0
Le Tout est souvent plus grand que la somme de ses parties.
@PascalOrtiz: Après avoir retesté ton code avec la chaîne "Aa0;|" j'obtiens True cela veut dire que lorsque tous les tests ont été éliminés, tout caractère invalide est accepté.
Sauf que l'énoncé ne dit rien de tel :
un projet à réaliser, dans lequel il m'est demandé de créer une application qui va générer un mot de passe aléatoire. Et ensuite de vérifier si ce même mot de passe contient: des majuscules, des minuscules, des chiffres et des caractères spéciaux(j'ai choisi de seulement utiliser: !"#$%&'-./:;<=>?@[\]^_` qui se trouve dans le code ascii entre 33-47 et 58-64 et 91-96).
Il n'est pas écrit que ce mot contienne exclusivement des caractères des catégories indiquées. D'ailleurs, il n'est pas indiqué quels caractères le générateur aléatoire utilise.
josmiley a écrit:
def verif(mdp):
res = 0
for c in mdp:
res |= c.islower() or c.isupper()*2 or c.isdecimal()*4 or c.isprintable()*8
if res == 15:
return True
Original ! Il me semble qu'il te manque un False final.
Pour ceux qui n'auraient pas compris, j'explique en deux mots. Le code utilise l'opérateur OU binaire représenté par | qui fonctionne de la manière suivante : si A et B sont des entiers positifs, on les écrit alignés en base 2, et dans chaque colonne du résultat, on écrit 1 sauf si les deux chiffres valent 0 auquel cas on écrit 0. Exemple avec 34|19 :
34 : 100010
19 : 010011
-------
110011
Dans son code, il utilise un entier r codé sur 4 bits qui traduisent la présence de :
minuscule (le poids faible)
majuscule
chiffre
ponctuation
A chaque tour de boucle, on ajoute à r le nombre suivant
c.islower() or c.isupper()*2 or c.isdecimal()*4 or c.isprintable()*8
qui vaut une puissance de 2 (1, 2, 4 ou 8) et place donc un bit valant 1 à une des positions correspondant à la catégorie du caractère (et ne fait rien si le caractère n'est dans aucune catégorie). On obtient un mdp valide si et seulement si, à un moment, chaque bit vaut 1 et donc si le nombre r vaut 1+2+4+8=15.
PierrotLeFou a écrit:
J'ai insisté à quelques reprises sur le fait qu'aucun code ne détecte les caractères invalides.
Parce que ce n'est pas demandé dans l'énoncé. La contrainte des 4 catégories donne une sécurité minimale, je peux augmenter la sécurité du mot de passe en choisissant un caractère d'une 5e catégorie.
Voici un autre code utilisant des ensembles et détecte les caractères invalides :
@josmiley: Tu dois évaluer toutes les fonctions pour chaque caractère ...
seulement si tous les caractères sont spéciaux puisque c'est le dernier test.
sinon les walrus c'était pas une bonne idée, et je me demande si un test ne vaut pas mieux qu'un affectation systématique. De plus en retournant (U,L,D,O) on a le statut du pwd:
def check_pwd(pwd):
U = False
L = False
D = False
O = False
for c in pwd:
if not U: U = c.isupper()
if not L: L = c.islower()
if not D: D = c.isdigit()
if not O: O = c in "!#\"$%&'-./:;<=>?@[\\]^_`"
if all((U,L,D,O)): break
return (U,L,D,O)
Cependant, je me demande si éliminer les tests concluants soit perspicace, si par exemple le mdp à beaucoup de minuscules, après le premier test de minuscule concluant, il faudra pour chaque minuscule suivant, faire 3 tests négatifs ...
PascalOrtiz a écrit:
Original ! Il me semble qu'il te manque un False final.
j'ai pensé que False ou None par défaut revenait au même. Cependant en retournant res, on a un statut du mot de passe: si la valeur retournée est 15 alors c'est bon, sinon les bits à zéro indiquent quelles catégories de caractères sont manquantes.
def verif(mdp):
res = 0
for c in mdp:
res |= c.islower() or c.isupper()*2 or c.isdecimal()*4 or c.isprintable()*8
if res == 15: break
return res
while True:
mdp = input('entrez un mdp à tester: ')
isOk = verif(mdp)
if isOk == 15:
print('mdp valide')
break
else:
if not isOk & 1: print('manque minuscule')
if not isOk & 2: print('manque majuscule')
if not isOk & 4: print('manque chiffre')
if not isOk & 8: print('manque caractères spécial')
print()
Une autre solution serait d'utiliser un dict de tous les caractères en clé associés à une valeur puissance de 2. Par exemple 1 pour les minuscules, 2 pour les majuscules, 4 etc ... comme le code précédent, mais on se passe des tests.
from string import ascii_lowercase,ascii_uppercase,digits,punctuation
chs = dict.fromkeys(ascii_lowercase,1)
chs.update(dict.fromkeys(ascii_uppercase,2))
chs.update(dict.fromkeys(digits,4))
chs.update(dict.fromkeys(punctuation,8))
def verif(mdp):
res = 0
for c in mdp:
res |= chs.get(c,0)
if res == 15: break
return res
Cependant en retournant res, on a un statut du mot de passe: si la valeur retournée est 15 alors c'est bon, sinon les bits à zéro indiquent quelles catégories de caractères sont manquantes.
Effectivement, bien vu ! tu dois sans doute faire de l'assembleur toi !
× 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.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Découverte Python Doc Tkinter Les chaînes de caractères
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Découverte Python Doc Tkinter Les chaînes de caractères
Découverte Python Doc Tkinter Les chaînes de caractères
Découverte Python Doc Tkinter Les chaînes de caractères
Découverte Python Doc Tkinter Les chaînes de caractères
Le Tout est souvent plus grand que la somme de ses parties.
Découverte Python Doc Tkinter Les chaînes de caractères
Le Tout est souvent plus grand que la somme de ses parties.
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.
Python c'est bon, mangez-en.
Le Tout est souvent plus grand que la somme de ses parties.
Découverte Python Doc Tkinter Les chaînes de caractères
Python c'est bon, mangez-en.
Découverte Python Doc Tkinter Les chaînes de caractères