如何为暴力破解密码的所有排列?
How to make all of the permutations of a password for brute force?
所以我试图制作一个暴力破解密码的程序。
首先,我编写了一个长度为1的密码程序:
password = input('What is your password?\n')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def brute_force():
for char in chars:
if char == password:
return char
print(brute_force())
然后我编辑了一个长度为2的密码:
def brute_force():
guess = [None, None]
for char in chars:
guess[0] = char
for char2 in chars:
guess[1] = char2
if ''.join(guess) == password:
return ''.join(guess)
最后我对长度为 3 的密码做了同样的事情:
def brute_force():
guess = [None, None, None]
for char in chars:
guess[0] = char
for char2 in chars:
guess[1] = char2
for char3 in chars:
guess[2] = char3
if ''.join(guess) == password:
return ''.join(guess)
我如何将此归纳为名为 length 的变量,该变量包含密码长度的整数值?
试试这个:
password = input('What is your password?\n')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
answer = ''
for i in range(len(password)):
for char in chars:
if char==password[i]:
answer += char
print(answer)
它不是使用嵌套循环,而是依次猜测每个字符。
您可以使用以下递归函数:
def brute_force(string, length, goal):
if not length:
if string == goal:
return string
return False
for c in chars:
s = brute_force(string + c, length - 1, goal)
if s:
return s
return False
您可以使用如下语法调用:
>>> brute_force('', 3, 'bob')
'bob'
>>> brute_force('', 2, 'yo')
'yo'
为什么这样做?
我们总是使用三个变量调用每个函数:string
、length
和 goal
。变量 string
保存了到目前为止的猜测,因此在第一个示例中,string
将是 bob
之前的所有内容,例如 ab
、bo
等等
下一个变量 length
保存在 string
达到正确长度之前还有多少个字符。
下一个变量 goal
是我们刚刚通过并与之比较的正确密码。
在函数的主体中,我们需要首先检查 length
是 0
的情况(通过检查 not length
来完成,因为 0
计算为 False
).当我们已经有了一个作为目标长度的字符串并且我们只想检查它是否正确时就是这种情况。
如果匹配,则我们 return 字符串,否则我们 return False
。我们 return 解决方案或 False
向调用我们的函数(堆栈中上面的调用)指示我们找到了正确的密码(或没有)。
我们现在已经完成了 length = 0
的案例,现在需要处理其他案例。
在这些情况下,目的是获取调用我们的字符串并循环遍历 chars
中的 all 个字符,每次调用brute_force
函数(递归),其结果是我们调用的字符串与该字符 (c
) 的串联结果。
这将创建一个类似影响的树,其中检查 每个 字符串直到原始 length
。
我们还需要知道在调用下一个函数时如何处理 length
和 goal
变量。
好吧,为了处理这些,我们只需要考虑下一个函数需要知道什么。它已经有了 string
(因为这是连接 chars
字符串中的下一个字符的结果)并且 length
只是少了一个,因为我们刚刚向string
通过连接和 goal
显然是相同的 - 我们仍在搜索相同的密码。
既然我们已经调用了这个函数,它将运行通过在它进行的每次后续调用中从长度中减去一个,直到它最终达到length == 0
的情况。我们又回到了简单的情况,并且已经知道该怎么做!
因此,在调用它之后,该函数将 return 两种情况之一,或者 False
表明最后一个节点没有找到密码(所以这会发生在某些情况下例如 ab
在我们搜索 bob
时到达终点,因此 return 在未找到解决方案后编辑 False
),或者,调用可以 return 实际 解决方案。
处理这些情况很简单,如果我们得到了实际的解决方案,我们只想 return 链上的那个,如果我们失败了 (False
),我们只想 return False
这将向我们上面的节点表明我们没有成功并告诉它继续搜索。
所以现在,我们只需要知道如何调用该函数即可。我们只需要发送一个空 string
和一个目标 length
和 goal
值并让递归发生。
请注意最后一件事,如果您希望它更简洁,您可以将函数定义修改为:
def brute_force(length, goal, string=''):
...
并更改其中的递归调用。这样,您可以使用类似以下内容的函数来调用该函数:brute_force(3, 'bob')
并且不需要指定 string
应该从哪里开始。这只是您可以根据需要添加的内容,但不是该功能运行所必需的。
这是一种解决方案:
password = input('What is your password? ')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def brute_force(length, check_callback, guess = ""):
if check_callback(guess):
return guess
elif len(guess) == length: #Reached maximum length and didn't find the password
return None
for char in chars:
retval = brute_force(length, check_callback, guess = guess + char)
if retval is not None:
return retval
return None #Couldn't find anything
print(brute_force(len(password), lambda guess: (guess == password))) #len(password) => cheating just for this example
length
是函数将达到的最大猜测长度。 check_callback
应该进行猜测,如果它有效,return 应该是一个真实值。函数 return 是第一个成功的猜测,或者 None
如果它找不到任何东西。
我承认我忘记了猜测的长度,提醒了我。
现在,即使猜测的长度还不正确,该函数也会检查正确答案,这在某些情况下很浪费。这是一个不这样做的函数:
def brute_force(length, check_callback, guess = ""):
if len(guess) == length: #Reached maximum length
return (guess if check_callback(guess) else None)
for char in chars:
retval = brute_force(length, check_callback, guess = guess + char)
if retval is not None:
return retval
return None #Couldn't find anything
print(brute_force(len(password), lambda guess: guess == password)) #len(password) => cheating just for this example
除了向您展示其工作原理的答案外,我还想提请注意以下事实,即标准库具有用于此目的的函数,其形式为 itertools.product
——而不是 itertools.permutations
因为这不允许重复,因此只会生成所有唯一字符的猜测:
from itertools import product
def brute_force():
for length in range(min_length, max_length + 1):
for p in product(chars, repeat=length):
guess = ''.join(p)
if guess == password:
return guess
所以我试图制作一个暴力破解密码的程序。
首先,我编写了一个长度为1的密码程序:
password = input('What is your password?\n')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def brute_force():
for char in chars:
if char == password:
return char
print(brute_force())
然后我编辑了一个长度为2的密码:
def brute_force():
guess = [None, None]
for char in chars:
guess[0] = char
for char2 in chars:
guess[1] = char2
if ''.join(guess) == password:
return ''.join(guess)
最后我对长度为 3 的密码做了同样的事情:
def brute_force():
guess = [None, None, None]
for char in chars:
guess[0] = char
for char2 in chars:
guess[1] = char2
for char3 in chars:
guess[2] = char3
if ''.join(guess) == password:
return ''.join(guess)
我如何将此归纳为名为 length 的变量,该变量包含密码长度的整数值?
试试这个:
password = input('What is your password?\n')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
answer = ''
for i in range(len(password)):
for char in chars:
if char==password[i]:
answer += char
print(answer)
它不是使用嵌套循环,而是依次猜测每个字符。
您可以使用以下递归函数:
def brute_force(string, length, goal):
if not length:
if string == goal:
return string
return False
for c in chars:
s = brute_force(string + c, length - 1, goal)
if s:
return s
return False
您可以使用如下语法调用:
>>> brute_force('', 3, 'bob')
'bob'
>>> brute_force('', 2, 'yo')
'yo'
为什么这样做?
我们总是使用三个变量调用每个函数:string
、length
和 goal
。变量 string
保存了到目前为止的猜测,因此在第一个示例中,string
将是 bob
之前的所有内容,例如 ab
、bo
等等
下一个变量 length
保存在 string
达到正确长度之前还有多少个字符。
下一个变量 goal
是我们刚刚通过并与之比较的正确密码。
在函数的主体中,我们需要首先检查 length
是 0
的情况(通过检查 not length
来完成,因为 0
计算为 False
).当我们已经有了一个作为目标长度的字符串并且我们只想检查它是否正确时就是这种情况。
如果匹配,则我们 return 字符串,否则我们 return False
。我们 return 解决方案或 False
向调用我们的函数(堆栈中上面的调用)指示我们找到了正确的密码(或没有)。
我们现在已经完成了 length = 0
的案例,现在需要处理其他案例。
在这些情况下,目的是获取调用我们的字符串并循环遍历 chars
中的 all 个字符,每次调用brute_force
函数(递归),其结果是我们调用的字符串与该字符 (c
) 的串联结果。
这将创建一个类似影响的树,其中检查 每个 字符串直到原始 length
。
我们还需要知道在调用下一个函数时如何处理 length
和 goal
变量。
好吧,为了处理这些,我们只需要考虑下一个函数需要知道什么。它已经有了 string
(因为这是连接 chars
字符串中的下一个字符的结果)并且 length
只是少了一个,因为我们刚刚向string
通过连接和 goal
显然是相同的 - 我们仍在搜索相同的密码。
既然我们已经调用了这个函数,它将运行通过在它进行的每次后续调用中从长度中减去一个,直到它最终达到length == 0
的情况。我们又回到了简单的情况,并且已经知道该怎么做!
因此,在调用它之后,该函数将 return 两种情况之一,或者 False
表明最后一个节点没有找到密码(所以这会发生在某些情况下例如 ab
在我们搜索 bob
时到达终点,因此 return 在未找到解决方案后编辑 False
),或者,调用可以 return 实际 解决方案。
处理这些情况很简单,如果我们得到了实际的解决方案,我们只想 return 链上的那个,如果我们失败了 (False
),我们只想 return False
这将向我们上面的节点表明我们没有成功并告诉它继续搜索。
所以现在,我们只需要知道如何调用该函数即可。我们只需要发送一个空 string
和一个目标 length
和 goal
值并让递归发生。
请注意最后一件事,如果您希望它更简洁,您可以将函数定义修改为:
def brute_force(length, goal, string=''):
...
并更改其中的递归调用。这样,您可以使用类似以下内容的函数来调用该函数:brute_force(3, 'bob')
并且不需要指定 string
应该从哪里开始。这只是您可以根据需要添加的内容,但不是该功能运行所必需的。
这是一种解决方案:
password = input('What is your password? ')
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def brute_force(length, check_callback, guess = ""):
if check_callback(guess):
return guess
elif len(guess) == length: #Reached maximum length and didn't find the password
return None
for char in chars:
retval = brute_force(length, check_callback, guess = guess + char)
if retval is not None:
return retval
return None #Couldn't find anything
print(brute_force(len(password), lambda guess: (guess == password))) #len(password) => cheating just for this example
length
是函数将达到的最大猜测长度。 check_callback
应该进行猜测,如果它有效,return 应该是一个真实值。函数 return 是第一个成功的猜测,或者 None
如果它找不到任何东西。
我承认我忘记了猜测的长度,
现在,即使猜测的长度还不正确,该函数也会检查正确答案,这在某些情况下很浪费。这是一个不这样做的函数:
def brute_force(length, check_callback, guess = ""):
if len(guess) == length: #Reached maximum length
return (guess if check_callback(guess) else None)
for char in chars:
retval = brute_force(length, check_callback, guess = guess + char)
if retval is not None:
return retval
return None #Couldn't find anything
print(brute_force(len(password), lambda guess: guess == password)) #len(password) => cheating just for this example
除了向您展示其工作原理的答案外,我还想提请注意以下事实,即标准库具有用于此目的的函数,其形式为 itertools.product
——而不是 itertools.permutations
因为这不允许重复,因此只会生成所有唯一字符的猜测:
from itertools import product
def brute_force():
for length in range(min_length, max_length + 1):
for p in product(chars, repeat=length):
guess = ''.join(p)
if guess == password:
return guess