how to make sure that a minimum of uppercase/lowercase/digits is generated into a string?

Question:

I have the task of modifying a password generator so that it generates the password with a minimum of respectively 2 uppercase, lowercase, digits and special characters as well as no 2 digits after each other. I am using the secrets module for generating and do not have a clue about modifying the outcome. The password generator is a template from a book which gives me no hints for this problem.

Here’s the generator, my first approach was to slide in a condition like a while loop between line 6 and 7.

import secrets
import string as s

def generate_password(length):
    chars = s.ascii_lowercase + s.ascii_uppercase + s.digits + s.punctuation
    password = ''
    while len(password) < length:
        password += secrets.choice(chars)
    return password

if __name__ == "__main__":
    while (n := int(input("Length of password? (min. 20)"))) < 20:
        pass
    password = generate_password(n)
    print(password)
Asked By: Timm Hagen

||

Answers:

There’s many different approaches to a problem like this. One is to generate a password, one random character at a time, keeping track of the rules and avoiding illegal characters (like a second digit in a row) and towards the end limiting the set of characters to ensure something gets picked that still has to go in. But that has the downside of some characters being more likely towards the end of the password.

Another approach would be to simply generate random strings of characters and write an efficient function to check if a password matches. This likely results in the simplest code, and will be easy to read, but can in theory take a long time, since it may generate a long string of invalid passwords. And if you’re not careful, you may accidentally set rules that make no password valid, causing the algorithm to never terminate.

Another approach still would be to ignore order and ensure you meet the rules first, and then generate random characters to fill out the password (still ensuring no more than half the characters are numbers) and then determine a random order using something like the Fisher-Yates shuffle, or something more efficient to come up with an ordering that has no 2 digits adjacent.

However it seems like this problem has been specifically designed to make it hard to write (since it’s not a very useful set of rules otherwise). You should give one of these approaches a try and share some code that is giving you trouble and ask a more specific question if you need help with it.

Answered By: Grismar
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.