如何解决最大递归深度错误

时间:2018-09-28 15:48:13

标签: python python-3.x

我正在生成具有所需长度的随机密码。我希望它至少有2个大写字母,2个小写字母,2个数字和2个特殊字符。我已经尝试了多种方法,但是每次遇到此递归深度错误。 谁能告诉我我做错了什么?

list_lower =['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']
list_upper = ['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'] 
list_digit = [1,2,3,4,5,6,7,8,9,0]
def generatePassword(desiredLength: int) -> str:
    x = 0
    password = ""
    for x in range (desiredLength):
        password = password + chr(random.randint(33,126))
        list(password)
        list_password = list(password)
        times_lower = 0
        times_upper = 0
        times_digit = 0
        times_special = 0
        for character in list_password:
            if character in list_lower:
                times_lower += 1
            elif character in list_upper:
                times_upper += 1
            elif character in list_digit:
                times_digit += 1
            else:
                times_special +=1
        if times_lower >= 2 and times_upper >= 2 and times_digit >= 2 and times_special >= 2:
            return password
        else:
            return generatePassword(desiredLength)

generatePassword(7)

第30行出现错误,该错误使函数递归。

3 个答案:

答案 0 :(得分:1)

调用generatePassword(7)永远不会生成具有4个不同类别中的2个类别的密码。

您根本不需要递归。

def generatePassword(desiredLength: int) -> str:
    while True:
        password = ""
        for x in range (desiredLength):
            password = password + chr(random.randint(33,126))
        times_lower = 0
        times_upper = 0
        times_digit = 0
        times_special = 0
        for character in password:
            if character in list_lower:
                times_lower += 1
            elif character in list_upper:
                times_upper += 1
            elif character in list_digit:
                times_digit += 1
            else:
                times_special +=1
        if times_lower >= 2 and times_upper >= 2 and times_digit >= 2 and times_special >= 2:
            return password
        else
            print ("Rejecting ", password)

如果要求生成长度为7或更短的密码,它将永远循环。我们可以通过先检查所需的长度来改善这一点

if desiredLength < 8:
    raise ArgumentError("Cannot generate passwords shorter than 8 characters")

答案 1 :(得分:0)

times_digit永远不会是> = 2,因为它会测试字符串(例如,“ 2”与列表中的整数相对,(例如2)将list_digit更改为

list_digit = ["1","2","3","4","5","6","7","8","9","0"]

然后重试。

通过这种方式可以更简单地完成操作,并且不需要递归函数。

答案 2 :(得分:0)

如果要生成密码,那么生成的密码实际上具有足够的随机性以至于无法预测,这一点很重要。

Random string generation with upper case letters and digits in Python

在如何生成真正随机的密码方面有很大的细目分类:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

(添加了“特殊字符”和“小写字符”以保留现有代码)

我知道这是一个有点倾斜的答案(即它不能直接回答问题),因此,如果您仍然需要“它必须包含这些类型的字符”,那么这是一个潜在的解决方案(即使这样做实际上会降低安全性) ):

import random
import string
from collections import Counter

def gen(N):
    return ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits + string.punctuation) for _ in range(N))

while True:
    pw = gen(8)
    counts = Counter(pw)
    upper = lower = digit = special = 0
    for (letter, count) in counts.items():
        if (letter in string.ascii_lowercase):
            lower += 1
        elif (letter in string.ascii_uppercase):
            upper += 1
        elif (letter in string.digits):
            digit += 1
        else:
            special += 1
            pass
    if (lower > 1 and upper > 1 and digit > 1 and special > 1):
        print("password is {}".format(pw))
        break
    print("failed password: {}".format(pw))