Python 如何解决最大递归深度错误
我正在生成一个具有所需长度的随机密码。我希望它至少有2个大写字母,2个小写字母,2个数字和2个特殊字符。我尝试过多种方法,但每次都出现递归深度错误。 谁能告诉我我做错了什么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'
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))