如何修改基于secrets模块的密码生成器以满足指定复杂度要求?
密码生成器修改方案
修改后的完整代码
import secrets import string as s def is_valid_password(password): # 校验各类字符数量是否达标 lower_count = sum(1 for c in password if c.islower()) upper_count = sum(1 for c in password if c.isupper()) digit_count = sum(1 for c in password if c.isdigit()) special_count = sum(1 for c in password if c in s.punctuation) # 校验是否存在连续数字 no_consecutive_digits = True for i in range(len(password)-1): if password[i].isdigit() and password[i+1].isdigit(): no_consecutive_digits = False break return (lower_count >= 2 and upper_count >= 2 and digit_count >= 2 and special_count >= 2 and no_consecutive_digits) def generate_password(length): all_chars = s.ascii_lowercase + s.ascii_uppercase + s.digits + s.punctuation non_digit_chars = s.ascii_lowercase + s.ascii_uppercase + s.punctuation while True: password = "" for _ in range(length): # 避免连续生成数字:如果最后一个字符是数字,只从非数字字符中选 if password and password[-1].isdigit(): next_char = secrets.choice(non_digit_chars) else: next_char = secrets.choice(all_chars) password += next_char # 验证密码是否符合所有规则,符合则返回 if is_valid_password(password): return password if __name__ == "__main__": while (n := int(input("密码长度?(最小20)"))) < 20: pass password = generate_password(n) print(password)
关键修改点
- 新增验证逻辑:专门编写
is_valid_password函数,逐一检查密码是否满足所有要求:每种字符(大写、小写、数字、特殊字符)至少2个,且无连续数字。 - 生成时规避连续数字:在生成每个字符前,判断密码最后一位是否为数字,如果是,就仅从非数字字符中选取下一个,减少无效生成的概率。
- 循环校验直到达标:外层用
while True循环,每次生成完整长度的密码后进行验证,只有符合所有规则的密码才会被返回。
这种方式既保留了secrets模块的安全性,又严格满足你提出的所有密码规则,同时通过生成时的小优化提升了效率。
内容的提问来源于stack exchange,提问作者Timm Hagen
相关产品推荐
相关产品推荐

