我想弄清楚如何生成一个不仅是唯一的,而且没有相似数字的数字列表 目的是使用crypt来破解样本哈希,我知道密码是唯一的,没有重复的数字和最多6位数
例>
[1,2,3,4,5,6,7,8,9...120, 123,124,125,126,127... 123456,123457...]
所以122或123451或12345673因为会有重复的数字
我的代码
#!/usr/bin/env python
from os import getuid
from crypt import crypt
import time
# all initialisation here
password = range(1000000)
# all initialisation ends here
def VerifyHash(shadowHashes, salt, user):
# crypt("Message", "Salt")
for i in password:
if (shadowHashes == crypt(str(i),salt)):
print "Password of %s is " % user + str(i)
break
else:
pass
def main():
with open('shadow.txt') as p:
for line in p:
shadowList = line
shadowHashes = shadowList.split(':')[1]
user = shadowList.split(':')[0]
salt = shadowHashes[:12]
VerifyHash(shadowHashes,salt,user)
main()
现在我使用范围(1000000)并且它有效但效率低,因为我所比较的数字是唯一的,没有重复数字所以我想让我的python程序更有效
请指出正确的方向
答案 0 :(得分:3)
对越来越多的重复数字使用itertools.permutations()
,最多9位,将这些数字与1到9之间的所有数字相结合(以防止生成带前导0的数字)。
from itertools import permutations
def generate_unique_numbers():
yield 0
for i in range(10):
for leading in '123456789':
if not i: # 1-digit numbers
yield int(leading)
continue
remaining_digits = '0123456789'.replace(leading, '')
for combo in permutations(remaining_digits, i):
yield int(leading + ''.join(combo))
这会生成所有这些有效数字,而不必跳过任何内容。有8877691这样的数字,范围从0到9876543210:
>>> sum(1 for _ in generate_unique_numbers())
8877691
>>> next(generate_unique_numbers())
0
>>> for i in generate_unique_numbers(): pass
...
>>> i
9876543210
输出的一些样本:
>>> from itertools import islice
>>> gen = generate_unique_numbers()
>>> list(islice(gen, 15))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15]
>>> list(islice(gen, 150, 165))
[204, 205, 206, 207, 208, 209, 210, 213, 214, 215, 216, 217, 218, 219, 230]
>>> list(islice(gen, 100000, 100015))
[542319, 542360, 542361, 542367, 542368, 542369, 542370, 542371, 542376, 542378, 542379, 542380, 542381, 542386, 542387]
>>> list(islice(gen, 1000000, 1000015))
[31279056, 31279058, 31279064, 31279065, 31279068, 31279084, 31279085, 31279086, 31279405, 31279406, 31279408, 31279450, 31279456, 31279458, 31279460]
这种方法比用range(9876543211)
生成所有数字然后过滤掉重复数字的数字(这是Moses Koledoye正在做的那样)要快得多:
>>> from timeit import timeit
>>> from itertools import islice
>>> def consume_n(it, n): next(islice(it, n, n), None)
...
>>> timeit('consume_n(gen(), 10000)', 'from __main__ import consume_n, unique_count as gen', number=100)
1.825788974761963
>>> timeit('consume_n(gen(), 10000)', 'from __main__ import consume_n, generate_unique_numbers as gen', number=100)
0.6307981014251709
上述代码仅为每种方法生成前10000个数字,并重复这些测试100次。我的方法很容易快3倍!
增加计数(并调整重复次数以保持可管理性),对比度增加:
>>> timeit('consume_n(gen(), 100000)', 'from __main__ import consume_n, unique_count as gen', number=10)
4.125269889831543
>>> timeit('consume_n(gen(), 100000)', 'from __main__ import consume_n, generate_unique_numbers as gen', number=10)
0.6416079998016357
现在差异已经增长了6倍。仅使用range
版本生成前一百万个数字 23秒,使用上述生成器生成.67秒
>>> timeit('consume_n(gen(), 1000000)', 'from __main__ import consume_n, unique_count as gen', number=1)
23.268329858779907
>>> timeit('consume_n(gen(), 1000000)', 'from __main__ import consume_n, generate_unique_numbers as gen', number=1)
0.6738729476928711
你走的系列越远,必须跳过更自然的数字,速度差异才会进一步增大;例如,必须跳过8800000000-8899999999范围内的所有数字,range()
方法将测试所有。这是1亿浪费的周期!
发生器可以在我的笔记本电脑上以6.7秒的速度生成所有可能的数字:
>>> from collections import deque
>>> def consume(it): deque(it, maxlen=0)
...
>>> timeit('consume(gen())', 'from __main__ import consume, generate_unique_numbers as gen', number=1)
6.6731719970703125
我没有敢于测试range()
方法需要多长时间;这些数字不到900万,但range()
方法将测试接近100亿种可能性,是所需数量的10000倍。
答案 1 :(得分:3)
当数字中的数字放在一个集合中时,您可以检查当表示为字符串时数字的长度是否相同:
def unique_count():
for i in range(1000000):
if len(str(i)) == len(set(str(i))):
yield i
该集合消除了重复的数字,因此没有重复数字的数字将通过该条件。
答案 2 :(得分:0)
您可以使用下面的生成函数获取最大数字i然后它将生成小于i唯一的数字的侦听,并且不重复数字。
def isDigitsRepeated(integer):
n = str(integer)
digits = []
for digit in n:
if digit in digits:
return True
digits += [digit]
return False
def generate(maximum):
lst = []
for x in range(maximum):
if not isDigitsRepeated(x):
lst += [x]
return lst