如何禁用一个循环的列表元素?
How to disable list elements for one cycle?
我写了一个密码生成脚本,它确保2个相同类型的字符不能出现在彼此后面:“12”或“ab”是不可能的。它总是必须是不同的类型,例如“1a”或“a%”或“aB”。
我目前是用这个来实现的:
# l1 - l4 are the last 4 symbols, l5 the current.
# n1 - n5 are just ones and zeros, depending if l on that position is a number
# For the problem I describe here just l5 and l4 would be necessary, but I have different 'policies',
# if you want 2 or 3 characters of the same type behind each other
if (l1.isupper() and l2.isupper()) or \ # characters upper
(l2.isupper() and l3.isupper()) or \
(l3.isupper() and l4.isupper()) or \
(l4.isupper() and l5.isupper()) or \
(l1.islower() and l2.islower()) or \
(l2.islower() and l3.islower()) or \
(l3.islower() and l4.islower()) or \
(l4.islower() and l5.islower()) or \ # characters lower
(n1 and n2) or (n2 and n3) or (n3 and n4) or (n4 and n5): # consecutive numbers
return False
虽然它确实工作得相当慢,因为如果函数 returns False
一个新的随机字符被采样并再次测试,直到找到一个有效字符。
我想过不用一大串字符,
char_list = ['A', ...'Z', 'a', ...'z', '0', ...'9', '!', ...'+'] # !...+ are symbols like !§$ and others
我可以把它分成不同的类型,像这样:
char_list = [['A', ...'Z'], ['a', ...'z'], ['0', ...'9'], ['!', ...'+']]
生成器可以选择其中一个列表,然后对一个字符进行采样,并在下一次迭代中简单地禁用该类型。这应该快得多,因为不可能连续两次使用相同的类型。但是我不知道如何实现这个 'disable for one cycle' 东西。
好吧,你可以做这样的事情,我确信它不是最优化性能的解决方案,但速度相当快,虽然我不知道你的用例 slow/fast 是什么:
import random
import string
def generate_password(length):
password = ""
char_pools = [
string.ascii_lowercase,
string.ascii_uppercase,
string.digits,
string.punctuation,
]
prev_pool = None
pool = random.choice(char_pools)
for _ in range(length):
while pool == prev_pool:
pool = random.choice(char_pools)
password += random.choice(pool)
prev_pool = pool
return password
虽然从密码学的角度来看我不确定这是否是一个安全的解决方案,因为您已经向攻击者提供了提示。如果他们可以从密码中识别出一个字符,他们就能够假定下一组可能的字符,这可以导致比暴力攻击更快的解密。
我写了一个密码生成脚本,它确保2个相同类型的字符不能出现在彼此后面:“12”或“ab”是不可能的。它总是必须是不同的类型,例如“1a”或“a%”或“aB”。
我目前是用这个来实现的:
# l1 - l4 are the last 4 symbols, l5 the current.
# n1 - n5 are just ones and zeros, depending if l on that position is a number
# For the problem I describe here just l5 and l4 would be necessary, but I have different 'policies',
# if you want 2 or 3 characters of the same type behind each other
if (l1.isupper() and l2.isupper()) or \ # characters upper
(l2.isupper() and l3.isupper()) or \
(l3.isupper() and l4.isupper()) or \
(l4.isupper() and l5.isupper()) or \
(l1.islower() and l2.islower()) or \
(l2.islower() and l3.islower()) or \
(l3.islower() and l4.islower()) or \
(l4.islower() and l5.islower()) or \ # characters lower
(n1 and n2) or (n2 and n3) or (n3 and n4) or (n4 and n5): # consecutive numbers
return False
虽然它确实工作得相当慢,因为如果函数 returns False
一个新的随机字符被采样并再次测试,直到找到一个有效字符。
我想过不用一大串字符,
char_list = ['A', ...'Z', 'a', ...'z', '0', ...'9', '!', ...'+'] # !...+ are symbols like !§$ and others
我可以把它分成不同的类型,像这样:
char_list = [['A', ...'Z'], ['a', ...'z'], ['0', ...'9'], ['!', ...'+']]
生成器可以选择其中一个列表,然后对一个字符进行采样,并在下一次迭代中简单地禁用该类型。这应该快得多,因为不可能连续两次使用相同的类型。但是我不知道如何实现这个 'disable for one cycle' 东西。
好吧,你可以做这样的事情,我确信它不是最优化性能的解决方案,但速度相当快,虽然我不知道你的用例 slow/fast 是什么:
import random
import string
def generate_password(length):
password = ""
char_pools = [
string.ascii_lowercase,
string.ascii_uppercase,
string.digits,
string.punctuation,
]
prev_pool = None
pool = random.choice(char_pools)
for _ in range(length):
while pool == prev_pool:
pool = random.choice(char_pools)
password += random.choice(pool)
prev_pool = pool
return password
虽然从密码学的角度来看我不确定这是否是一个安全的解决方案,因为您已经向攻击者提供了提示。如果他们可以从密码中识别出一个字符,他们就能够假定下一组可能的字符,这可以导致比暴力攻击更快的解密。