简体   繁体   中英

random password does not choose every condition that user choose

I want to make a password generator I let user to choose upper, digits and, symbols but I have problem with Random part when my code choose a random password from phrase According to the conditions selected by the user, one of the conditions may not be fulfilled. For example, all the selected phrase may be lowercase, but the user has activated the uppercase condition

import  string
import secrets


def random_password_generator(upper=True, digits=True, symbols=False, length=12):
    a_l = string.ascii_lowercase
    a_u = string.ascii_uppercase
    phrase = a_l
    if upper:
        phrase += a_u

    if digits:
        phrase += string.digits

    if symbols:
        phrase += string.punctuation

    password = ''.join(secrets.choice(phrase) for i in range(length))

    return password

a = random_password_generator()
print(a)

secrets.choice(phrase) chooses a random character out of the phrase you give it. You perform that operation 10 times. There is no guarantee that during those 10 times, the random choice will fall in any of the categories you have added to your phrase.

password = ''.join(secrets.choice(phrase) for i in range(10))

You're choosing ten random letters from phrase .

Even if phrase includes uppercase letters as possible choices, there's no guarantee that the random selections will actually include any uppercase letters. It might just happen to randomly choose all lowercase letters.

Same thing with digits and symbols.

Also, why are you choosing ten letters? You're ignoring the length parameter.

Take the input length and divide it into symbol categories. Randomly select characters from that category and append them to the password. Finally, randomly shuffle all characters of the password.

Dividing the input length into categories could be done according to some weights that you choose and hard-code.

For example, if you were to assign the following weights,

Category weight
Upper 5
Lower 5
Digits 3
Symbols 2

Then, you can decide how many characters to use for each category. For example, if they ask for a length of 12, with upper, lower, and digits. The total weight for upper, lower, and digits is 5 + 5 + 3 = 13, therefore max(( 5 / 13 ) * 12, 1) = 4 characters should be upper case, etc.

Your function argument to decide wether symbols should be included is called symbols . However, you then assign string.punctuation to a variable with the same name.

This means, the following if statement if symbol: is actually the same as if string.punctuation , which always resolves to True , no matter what boolean value your symbol parameter carried before string.punctuation was assigned to it.

Here is a fixed version of your code:

import  string
import secrets


def random_password_generator(upper=True, digits=True, include_symbols=False, length=12):
    a_l = string.ascii_lowercase
    a_u = string.ascii_uppercase
    all_symbols = string.punctuation # make sure this is a different variable
    phrase = a_l
    if upper:
        phrase += a_u

    if digits:
        phrase += string.digits

    if include_symbols:
        phrase += all_symbols

    password = ''.join(secrets.choice(phrase) for i in range(10))

    return password

a = random_password_generator()
print(a)

I hope this was understandable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM