Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何解决最大递归深度错误_Python_Python 3.x - Fatal编程技术网

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

Python 如何解决最大递归深度错误,python,python-3.x,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'

我正在生成一个具有所需长度的随机密码。我希望它至少有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行得到了一个错误,这使得函数递归。

调用
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")
如果需要长度<8:
引发ArgumentError(“无法生成短于8个字符的密码”)

次数\u位
永远不会>=2,因为它会对列表中的整数测试stings(例如“2”),(例如2)将您的
列表\u位
更改为

list_digit = ["1","2","3","4","5","6","7","8","9","0"]
然后再试一次


顺便说一句,这可以做得简单得多,而且不需要递归函数。

如果您要生成密码,那么生成的密码必须具有足够的随机性,不可预测

详细介绍了如何生成真正随机的密码:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
(省略添加“特殊字符”和“小写字符”以保留现有代码)

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


为什么要递归呢?这看起来不像是一个自然的用例。另外--请不要使用像“第30行”这样的东西。编辑器的行号不会保留在代码中。您的中断条件基于随机性。无论您做什么,重复出现太多次的可能性始终为非零。首先,函数的基本大小写不正确:当
desiredLength
为0时,函数返回
None
,而不是空字符串。其次,函数使用相同的值
desiredLength
(必须是
desiredLength-1
)调用自身。进行递归调用的
if-else
分支不应该在内部for循环之外吗?否则,它永远不可能具有您希望的属性(因为
len(password)==1
)因此,它总是进行递归调用。不管怎样,只要使用
while
循环。不需要递归。此外,即使使用while循环,也有更好的方法。从您需要的每个类别中随机选择2个字符。然后随机选择一个类别和一个字符,直到您填满所需的长度。然后洗牌。其他人也会这样做我已经指出,代码中还有很多问题。
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))