我最近读了杰夫的博客文章,题为“aa>”,其中他提到,通过利用你的GPU的力量,你可以很快地解决问题。
我想知道是否可以利用GPU的能力来散列Python(MD5、SHA-1等)中的内容?
我对这个很感兴趣,因为我想知道我能以多快的速度强行处理事情(不是真实世界的事情,从旧的泄漏数据转储)。
目前,我正在做这类事情(简化示例):from itertools import product
from hashlib import md5
hashes = ["some","hashes"]
chars = []
for i in range(97,123): # a-z only
chars.append(chr(i))
for i in range(1,6): # all combos of a-z, 1-5 chars
for c in product(chars,repeat=i):
s = ''.join(c)
if md5(s).hexdigest() in hashes:
print "Found",s
但我想知道是否有一种方法可以加快使用GPU的速度?我想我需要一个可以连续生成这样散列的模块-有人知道吗?
最佳答案
有两个障碍:
在GPU上编写要执行的程序。afaik目前还没有将python程序转换为GPU执行的代码的机制。所以除非你能找到你所需要的(这可能是可能的,因为它看起来是一个相当常见的用例),否则你必须使用一种GPU编程语言(CUDA,OpenCL,Haskell,…)
从python调用在GPU上运行的程序,并交换数据。有几个python+cuda项目可以完成这一部分:
http://mathema.tician.de/software/pycuda
http://code.google.com/p/pystream/
https://launchpad.net/python-cuda
通过适当的搜索,您可能会发现更多。
同样Python GPU programming看起来相关
然后,python程序将使用第2部分中的技术或等效技术之一加载和调用GPU“内核”(使用本答案第1部分中的技术创建的程序)。
编辑
您可以生成整个“蛮力”值集,以及GPU上的MD5哈希。然后使用python检索结果。这可能比在Python中生成值、将它们传递给GPU、然后返回MD5更容易。
如果我已经理解了,程序将生成所有1个字符、2、3、4、5和6个小写字母字符串,并生成MD5哈希,是吗?
伊迪丝2-我之前的分析完全错了-我道歉
edit3:skimingWikipedia MD5似乎可以优化计算一个定长字符串(例如6个ASCII字符)的MD5。
根据维基百科的伪代码,它只有64个循环,16个循环的迭代组使用相同的算法。因此,如果键小于55字节,计算的核心可以从以下位置“展开”:for i from 0 to 63
if 0 ≤ i ≤ 15 then
f := (b and c) or ((not b) and d)
g := i
else if 16 ≤ i ≤ 31
f := (d and b) or ((not d) and c)
g := (5×i + 1) mod 16
else if 32 ≤ i ≤ 47
f := b xor c xor d
g := (3×i + 5) mod 16
else if 48 ≤ i ≤ 63
f := c xor (b or (not d))
g := (7×i) mod 16
temp := d
d := c
c := b
b := b + leftrotate((a + f + k[i] + w[g]) , r[i])
a := temp
end for
到:
// i == 0
f := (b and c) or ((not b) and d) // +4 ops
// g := i
temp := d
d := c
c := b
b := b + leftrotate((a + f + k[0] + w[0]) , r[0]) // 9 ops
a := temp
// i == 1
f := (b and c) or ((not b) and d)
// g := i
temp := d
d := c
c := b
b := b + leftrotate((a + f + k[1] + w[1]) , r[1])
a := temp
展开会导致一些数组索引是常量,这应该允许一个好的GPU编译器进行更多的常量传播。这可能会带来显著的改善。每一步大约有9个操作,编译器将需要处理5个数据块,因此大约有14个操作/步骤*64个步骤,大约有1000个操作。
编辑4:
格勒克!我读过更多的维基百科MD5算法——MD5比我想象的更容易被攻击。只有每组16的前两个循环直接使用6字节的变量键字符串,其余的字符串是常量。算法的其余部分正在进行洗牌和逐位操作,这些操作可能需要进行非常重要的进一步优化。每16个循环中只有2个涉及密钥,那么速度可能高达8倍,也可能超过4倍。
因此,与1024个核心GPU不同的是,它以1GHz的速度运行,每微秒产生1024个哈希,而不是4096个/微秒或8096个/秒=4-8个哈希/纳秒。
大约有27^6个键=387420489个键,因此MD5哈希。
387420489键/4-8/纳秒约=0.05-0.1秒
主机和GPU之间的通信将非常缓慢,但不可能超过100%。
所以大约在0.1秒到0.2秒之间。
MD5散列为16个字节,因此如果要存储它,则会消耗6.2 GB。在两个现代GPU上,每个GPU只需要2个传输,但这将是一个非常重要的开销。如果散列值保存到磁盘(甚至使用SSD),或者在10Gbit以太网上移动,那么散列生成会被I/O时间淹没。
只有94个可打印的ASCII字符,因此对于每个ASCII 6字符键:
94^6=689869781056键/4-8/纳秒=86-172秒
哦,我的天哪!-(
长钥匙,还有比MD5更好的东西!
也许试着写一个python程序来生成最佳的gpu算法?
通过“展开”python程序中的循环来生成gpu“kernel”的文本,并打印直线计算的文本,并填充所有常量。
然后尝试找出计算每个键长度的MD5的最佳指令序列。使用展开的程序,尝试跟踪每个位上的操作和依赖项,然后尝试将这些位及其操作重新组合成连续的32位字和新的直线计算。(说句公道话,也许GPU编译器也能做到这一点?可能有兴趣了解)