Python의 첫 번째 암호 생성기

Sep 10 2020

이것은 Python을 사용하는 첫 번째 프로젝트입니다. 사용자 입력을 확인하는 간단한 암호 생성기를 만들었습니다. 어떻게 개선 할 수 있습니까?

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

사용 예 :

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

답변

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

이 알파벳 쓰기 방법은 오류가 발생하기 쉽습니다. 대신 가져 와서 string사용 합니다. 어떤 이유로 든 자신 만의 글자 범위를 생성하고 싶다면string.ascii_lowercaseletters

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

문자를 생략하거나 복제 할 위험이 없기 때문입니다.


password_length = 0
password_numbers = []
password_letters = []

이러한 기본값은 사용되지 않습니다. 의 기본값 password_numbers과는 password_letters그 변수가 숫자를 유지하기 때문에 이해가되지 않습니다. 세 줄을 모두 삭제하겠습니다.


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

나는 대신 쓸 것이다

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

while항상 첫 번째 반복에서 벗어나기 때문에 여기 에 루프 가 있다는 것은 의미가 없습니다 .


range(0,password_numbers)

그냥 쓸 수 있습니다 range(password_numbers).


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

이것은 0에서 8까지의 숫자를 추가합니다. 9는 아닙니다 random.randrange(10). 10 개의 숫자를 모두 원하면 . 또는 더 나은 방법은 random.choice(string.digits).


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

사용 string.digits하면의 모든 요소가 password문자가되므로이를 password_string = ''.join(password).

6 Anonymous Sep 10 2020 at 20:31

임의의 문자열을 생성하는보다 간단한 방법 :

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)

여기 에서 빌려 왔으며 더 많은 예가 있습니다.

이제 최소 자릿수와 같은 특정 요구 사항이있는 경우 수식을 조정하거나 두 개의 목록을 생성하고 값을 섞으면 서 병합 할 수 있습니다.

위에서 인용 한 링크에 예가 있습니다. "고정 된 수의 문자와 숫자로 임의의 영숫자 문자열 생성"=> 두 개의 목록 이해를 병합합니다.

당신이하는 방식은 절차 적이지만 Pythonic은 아닙니다. 그것은 바퀴를 재창조하는 것입니다.

최소한 허용되는 문자 목록은 다음과 같아야합니다.

letters = "abcdefghijklmnopqrstuvwxyz"

그런 다음 임의의 문자를 선택합니다. 예를 들어 letters[3]목록이 0 기반이고 Python은 문자열을 문자 시퀀스로 취급하므로 'd'를 반환합니다. 이미하고있는 것처럼 셔플을 사용하면 더 간결한 코드를 작성할 수 있습니다.

3 K.Oleksy Sep 10 2020 at 19:19

먼저

각 while 루프에 대해 별도의 메서드를 만드는 것이 좋습니다.

둘째

"while True"루프는 좋은 습관이 아니라고 생각합니다. 대신 조건을 사용하십시오.

제삼

코드를 포함 할 PasswordGenerator 클래스를 만드는 것이 좋습니다. 앞으로 코드를 확장하는 데 도움이 될 것입니다.

프로젝트의 기본 구조

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

마지막으로 한 가지 책임으로 기능을 만드는 것을 잊지 마십시오. 그 후 각각에 대한 단위 테스트를 작성할 수 있으며 더 쉬울 것입니다.