Penghasil kata sandi pertama dengan Python

Sep 10 2020

Ini adalah proyek pertama saya menggunakan Python. Saya membuat pembuat kata sandi sederhana yang memeriksa input pengguna. Bagaimana cara memperbaikinya?

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

Contoh penggunaan:

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

Jawaban

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"]

Metode penulisan alfabet ini sangat rawan kesalahan. Saya akan mengimpor stringdan menggunakan string.ascii_lowercasesebagai ganti letters. Jika Anda ingin membuat rangkaian huruf Anda sendiri untuk alasan apa pun, saya akan menulis

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

karena tidak ada bahaya menghilangkan atau menggandakan surat.


password_length = 0
password_numbers = []
password_letters = []

Nilai default ini tidak pernah digunakan. Default untuk password_numbersdan password_letterstidak masuk akal karena variabel tersebut berisi angka. Saya akan menghapus ketiga baris tersebut.


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

Saya malah akan menulis

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

Tidak ada gunanya memiliki whileloop di sini karena Anda selalu keluar dari iterasi pertama.


range(0,password_numbers)

Anda tinggal menulis range(password_numbers).


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

Ini akan menambahkan digit dari 0 sampai 8 inklusif, tidak pernah 9. Jika Anda ingin semua sepuluh digit Anda harus menulis random.randrange(10). Atau, mungkin lebih baik, gunakan random.choice(string.digits).


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

Jika Anda menggunakan string.digitsmaka setiap elemen passwordakan menjadi karakter sehingga Anda dapat menyederhanakannya menjadi password_string = ''.join(password).

6 Anonymous Sep 10 2020 at 20:31

Cara yang lebih mudah untuk menghasilkan string acak:

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)

dipinjam dari sini , dan ada lebih banyak contoh.

Sekarang jika Anda memiliki persyaratan khusus seperti jumlah digit minimum, Anda dapat mengubah rumus, atau membuat dua daftar dan menggabungkannya sambil mengacak nilainya.

Ada contoh di tautan yang saya kutip di atas: "Buat string alfanumerik acak dengan jumlah huruf dan angka yang tetap" => menggabungkan dua pemahaman daftar.

Cara Anda melakukannya adalah prosedural tetapi bukan Pythonic. Ini seperti menciptakan kembali roda.

Paling tidak, daftar karakter yang diizinkan harus terlihat seperti ini:

letters = "abcdefghijklmnopqrstuvwxyz"

Kemudian Anda memilih huruf acak misalnya letters[3]akan mengembalikan 'd' karena daftarnya berbasis 0 dan Python memperlakukan string sebagai urutan karakter. Menggunakan shuffle seperti yang sudah Anda lakukan, Anda dapat menulis kode yang lebih ringkas.

3 K.Oleksy Sep 10 2020 at 19:19

Pertama

Saya sarankan membuat metode terpisah untuk setiap while loop.

Kedua

Perulangan "sementara Benar" bukanlah praktik yang baik, saya pikir. Alih-alih itu, gunakan kondisi.

Ketiga

Saya sarankan membuat kelas PasswordGenerator yang akan berisi kode Anda. Ini akan membantu Anda untuk memperluas kode Anda di masa depan.

Struktur dasar untuk proyek Anda

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

Untuk akhirnya ingatlah untuk membuat fungsi dengan satu tanggung jawab. Setelah itu, Anda dapat menulis tes unit untuk masing-masing itu dan itu akan lebih mudah.