用Python生成暴力破解字典

标签:Python

事先声明一下,我只是一时兴起,绝对没有去做和谐的事,各位也请自重=。=

其实暴力破解字典就是将可输入的字符进行全排列,是非常简单的方法,只不过用C语言写起来很繁琐,因此我想到了Python。

先看看怎么生成所有可输入的字符吧(不考虑中文等字符),方法很多,这里列举2种:
chars = string.printable[:-5] # 后面5个是换行、tab等字符
chars = ''.join([chr(i) for i in xrange(32, 127)])
取下长度就发现有95个字符…

生成2位的全排列麻烦一些:
p = []
for i in chars:
	for j in chars:
		p.append(i + j)
当然也可以直接用列表来生成:
p = [i + j for i in chars for j in chars]
生成更多位当然也可以用更多的变量来实现,但如果位数是变量,那我就不知道得写几个了。
不过这也很简单,因为Python是动态语言,我只要动态构造一个列表解析即可:
n = 3
pattern = '["' + '%%s' * n + '" %% (' + 'i%d,' * n + ')' + ' for i%d in chars' * n + ']'
pattern %= tuple(range(n) * 2)
p = eval(pattern)
你会发现当n大于3时,生成已经慢得要死了,而且很可能出现内存错误。因为954 = 81450625,已经接近1亿了,要在内存里放那么多字符串可不容易。

最容易想到的方法就是改成生成器表达式,也就是把中括号改成小括号,这样瞬间就生成了,而遍历的方法仍然是用for。
不过用eval总觉得有些不好,生成的式子也很难看懂。于是切换到Python 2.6,用itertools.product()函数就行了:
import itertools
import string
n = 3
itertools.product(string.printable[:-5], repeat=n)
没有2.6咋办呢,看看文档里给出的源码吧,写得比我的易懂些,但是性能会差一些(速度约为我的1/4):
def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)
注意result用的是列表解析,事实上用生成器表达式更节省内存。
当然,标准模块是C实现,所以速度仍然是比我快很多的。

此外,因为是生成1~n位的全排列,所以还得合并生成器。如果是自己写yield的,那只要再套个for循环即可;而如果是用生成器表达式,写起来就麻烦多了。
好在itertools里还有chain()和chain.from_iterable()这2个函数(后者为2.6新增)。

于是最终的函数如下:
import itertools
import string

def crackdict(max, min=1, chars=None):
	assert max >= min >= 1

	if chars is None:
		import string
		chars = string.printable[:-5]

	p = []
	for i in xrange(min, max + 1):
		p.append(itertools.product(string.printable[:-5], repeat=i))

	return itertools.chain(*p)

#测试一下:
max, min = 4, 1
d = crackdict(max, min)

print sum((1 for i in d))
print sum([95 ** i for i in xrange(min, max + 1)])
4位一共用生成了82317120个(95 + 952 + 953 + 954)字符串,时间为14.4秒左右。

记得以前报导说每秒可以尝试2万个密码,因此4位只要1小时左右就能破解了。
如果使用7位密码的话,一共是70576641626495种组合,就算现在电脑强大了,每秒破解1百万个,平均也要400多天。
嗯,突然发现我最常用的密码就是7位,强烈鄙视那些强制要求8位、12位密码的网站和软件。

2条评论 你不来一发么↓ 顺序排列 倒序排列

    向下滚动可载入更多评论,或者点这里禁止自动加载

    想说点什么呢?