Premier générateur de mot de passe en Python
C'est mon premier projet utilisant Python. J'ai créé un simple générateur de mots de passe qui vérifie les entrées de l'utilisateur. Comment puis-je l'améliorer?
import random
def password_generator():
password = []
letters = ["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"]
password_length = 0
password_numbers = []
password_letters = []
# Input the length of the password
while True:
password_length_input = input("Choose the length of your password with numbers between 6 and 15:\n")
if not password_length_input.isnumeric():
print(f"{password_length_input} is not a number, try again:")
continue
else:
password_length = int(password_length_input)
print(f"Password length: {password_length}")
if 6 <= password_length <= 15:
break
else:
print("The password must be between 6 and 15 characters, try again:")
continue
# Input the amount of numbers in password
while True:
password_numbers_input = \
input(f"Choose the amount of numbers you want in your password, max {password_length}\n")
if not password_numbers_input.isnumeric():
print(f"{password_numbers_input} is not a number try again")
continue
elif int(password_numbers_input) > password_length:
password_numbers = 0
print(f"The value is too high, choose maximum {password_length} numbers")
continue
else:
password_numbers = int(password_numbers_input)
print(f"Password numbers: {password_numbers}")
for number in range(0,password_numbers):
password.append(random.randrange(0,9))
break
# Check for numbers and letters in password
while True:
if password_numbers == password_length:
print(f"The password will be only {password_numbers} numbers, no letters.")
break
else:
password_letters = password_length - password_numbers
print(f"""Your password will be {password_length} characters with {password_numbers} numbers and {password_letters} letters.""")
for letter in range(0,password_letters):
password.append(random.choice(letters))
break
random.shuffle(password)
password_string = ''.join([str(item) for item in password])
print(f"Your password is:\n{password_string}")
password_generator()
Exemple d'utilisation:
Choose the length of your password with numbers between 6 and 15:
Password length: 8
Choose the amount of numbers you want in your password, max 8
Password numbers: 2
Your password will be 8 characters with 2 numbers and 6 letters.
Your password is:
pzc11bmf
Réponses
letters = ["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"]
Cette méthode d'écriture de l'alphabet est très sujette aux erreurs. J'importerais stringet utiliserais string.ascii_lowercaseà la place de letters. Si vous souhaitez générer votre propre gamme de lettres pour une raison quelconque, j'écrirais
letters = [chr(n) for n in range(ord('a'), ord('z') + 1)]
puisqu'il n'y a alors aucun risque d'omettre ou de dupliquer une lettre.
password_length = 0 password_numbers = [] password_letters = []
Ces valeurs par défaut ne sont jamais utilisées. Les valeurs par défaut pour password_numberset password_lettersn'ont pas de sens puisque ces variables contiennent des nombres. Je supprimerais les trois lignes.
if not password_length_input.isnumeric(): print(f"{password_length_input} is not a number, try again:") continue else: password_length = int(password_length_input) print(f"Password length: {password_length}")
J'écrirais plutôt
try:
password_length = int(password_length_input)
except ValueError:
print(f"{password_length_input} is not a number, try again:")
continue
print(f"Password length: {password_length}")
while True: if password_numbers == password_length: ... break else: ... break
Il n'y a aucun sens à avoir une whileboucle ici puisque vous en sortez toujours à la première itération.
range(0,password_numbers)
Vous pouvez simplement écrire range(password_numbers).
password.append(random.randrange(0,9))
Cela ajoutera un chiffre de 0 à 8 inclus, jamais 9. Si vous voulez les dix chiffres, vous devez écrire random.randrange(10). Ou, peut-être mieux, utilisez random.choice(string.digits).
password_string = ''.join([str(item) for item in password])
Si vous utilisez string.digitsalors chaque élément de passwordsera un caractère afin que vous puissiez simplifier cela en password_string = ''.join(password).
Une manière plus simple de générer une chaîne aléatoire:
import random
import string
def get_random_string(length):
letters = string.ascii_lowercase
result_str = ''.join(random.choice(letters) for i in range(length))
print("Random string of length", length, "is:", result_str)
get_random_string(8)
get_random_string(8)
get_random_string(6)
emprunté d' ici , et il y a plus d'exemples.
Désormais, si vous avez des exigences spécifiques telles qu'un nombre minimum de chiffres, vous pouvez soit modifier la formule, soit générer deux listes et les fusionner tout en mélangeant les valeurs.
Il y a un exemple dans le lien que j'ai cité ci-dessus: "Générer une chaîne alphanumérique aléatoire avec un nombre fixe de lettres et de chiffres" => fusionner deux compréhensions de liste.
La façon dont vous le faites est procédurale mais pas pythonique. Il réinvente un peu la roue.
À tout le moins, votre liste de caractères autorisés devrait ressembler à ceci:
letters = "abcdefghijklmnopqrstuvwxyz"
Ensuite, vous choisissez une lettre aléatoire, par exemple letters[3]retournera «d» puisque la liste est basée sur 0 et Python traite les chaînes comme des séquences de caractères. En utilisant la lecture aléatoire comme vous le faites déjà, vous pouvez écrire un code plus concis.
Première
Je suggère de créer des méthodes distinctes pour chaque boucle while.
Seconde
La boucle "while True" n'est pas une bonne pratique, je pense. Au lieu de cela, utilisez condition.
Troisième
Je suggère de créer la classe PasswordGenerator qui contiendra votre code. Cela vous aidera à développer votre code à l'avenir.
Structure de base pour votre projet
class PasswordGenerator():
check_declared_password_length():
...
check_amount_of_password_numbers():
...
*
*
*
Pour la fin, pensez à créer des fonctions avec une seule responsabilité. Après cela, vous pouvez écrire des tests unitaires pour chacun d'entre eux et ce sera plus facile.