Erster Passwortgenerator in Python

Sep 10 2020

Dies ist mein erstes Projekt mit Python. Ich habe einen einfachen Passwortgenerator erstellt, der Benutzereingaben überprüft. Wie kann ich es verbessern?

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()

Anwendungsbeispiel:

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

Antworten

9 benrg Sep 10 2020 at 22:06
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"]

Diese Methode zum Schreiben des Alphabets ist sehr fehleranfällig. Ich würde anstelle von importieren stringund verwenden . Wenn Sie aus irgendeinem Grund Ihre eigenen Buchstaben erstellen möchten, würde ich schreibenstring.ascii_lowercaseletters

letters = [chr(n) for n in range(ord('a'), ord('z') + 1)]

da dann keine Gefahr besteht, einen Brief wegzulassen oder zu duplizieren.


password_length = 0
password_numbers = []
password_letters = []

Diese Standardwerte werden niemals verwendet. Die Standardeinstellungen für password_numbersund password_letterssind nicht sinnvoll, da diese Variablen Zahlen enthalten. Ich würde alle drei Zeilen löschen.


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}")

Ich würde stattdessen schreiben

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

Es macht keinen Sinn, hier eine whileSchleife zu haben, da Sie bei der ersten Iteration immer aus dieser Schleife ausbrechen.


range(0,password_numbers)

Du kannst einfach schreiben range(password_numbers).


password.append(random.randrange(0,9))

Dadurch wird eine Ziffer von 0 bis einschließlich 8 angehängt, niemals 9. Wenn Sie alle zehn Ziffern möchten, sollten Sie schreiben random.randrange(10). Oder vielleicht besser verwenden random.choice(string.digits).


password_string = ''.join([str(item) for item in password])

Wenn Sie verwenden, string.digitsist jedes Element von passwordein Zeichen, sodass Sie dies vereinfachen können password_string = ''.join(password).

6 Anonymous Sep 10 2020 at 20:31

Eine einfachere Möglichkeit, eine zufällige Zeichenfolge zu generieren:

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)

von hier ausgeliehen , und es gibt weitere Beispiele.

Wenn Sie spezielle Anforderungen wie eine Mindestanzahl von Ziffern haben, können Sie entweder die Formel optimieren oder zwei Listen erstellen und diese zusammenführen, während Sie die Werte mischen.

Der oben zitierte Link enthält ein Beispiel: "Generieren Sie eine zufällige alphanumerische Zeichenfolge mit einer festen Anzahl von Buchstaben und Ziffern" => Zusammenführen von zwei Listenverständnissen.

Die Art und Weise, wie Sie es tun, ist prozedural, aber nicht pythonisch. Es erfindet das Rad irgendwie neu.

Zumindest sollte Ihre Liste der zulässigen Zeichen folgendermaßen aussehen:

letters = "abcdefghijklmnopqrstuvwxyz"

Dann wählen Sie einen zufälligen Buchstaben aus, z. B. letters[3]wird 'd' zurückgegeben, da die Liste auf 0 basiert und Python Zeichenfolgen als Zeichenfolgen behandelt. Wenn Sie Shuffle verwenden, wie Sie es bereits tun, können Sie präziseren Code schreiben.

3 K.Oleksy Sep 10 2020 at 19:19

Zuerst

Ich schlage vor, für jede while-Schleife separate Methoden zu erstellen.

Zweite

"while True" -Schleife ist keine gute Praxis, denke ich. Verwenden Sie stattdessen Bedingung.

Dritte

Ich schlage vor, eine PasswordGenerator-Klasse zu erstellen, die Ihren Code enthält. Es wird Ihnen helfen, Ihren Code in Zukunft zu erweitern.

Grundstruktur für Ihr Projekt

 class PasswordGenerator():
     
    check_declared_password_length():
        ...
        
    check_amount_of_password_numbers():
        ...
    *
    *
    *

Denken Sie am Ende daran, Funktionen mit einer Verantwortung zu erstellen. Danach können Sie Unit-Tests für jedes dieser Elemente schreiben, und es wird einfacher.