有两个障碍:
- 编写一个在 GPU 上执行的程序。 AFAIK,目前没有可用的机制将 Python 程序转换为 GPU 执行的代码。因此,除非您能找到您需要的东西(这可能是可能的,因为它看起来像是一个相当常见的用例),否则您将必须使用一种 GPU 编程语言(CUDA、OpenCL、Haskell 等)来实现这一点。 .)
-
从Python调用GPU上运行的程序,并交换数据。有几个 Python+CUDA 项目可以完成这部分工作:
- http://mathema.tician.de/software/pycuda http://mathema.tician.de/software/pycuda
- http://code.google.com/p/pystream/ http://code.google.com/p/pystream/
- https://launchpad.net/python-cuda https://launchpad.net/python-cuda
通过适当的搜索,您可能会发现更多。
Also Python GPU 编程 https://stackoverflow.com/questions/5957554/python-gpu-programming看起来相关
然后,Python 程序将使用第 2 部分或同等技术之一加载并调用 GPU“内核”(使用本答案第 1 部分中的技术创建的程序)。
编辑
您可以在 GPU 上生成整套“暴力”值和 md5 哈希值。然后只需使用 Python 检索结果即可。这可能比在 Python 中生成值、将它们传递到 GPU、然后返回 md5 更容易。
如果我理解的话,程序会生成所有 1 个字符、2、3、4、5 和 6 个小写字母字符串,并生成 md5 哈希,是吗?
Edit2 - 我之前的分析完全错误 - 我很抱歉
编辑3:略读维基百科 MD5 http://en.wikipedia.org/wiki/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
to:
// 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 个操作。
Edit4:
Glerk!我阅读了更多关于 Wikipedia MD5 算法的内容 - MD5 比我想象的更容易攻击。每组 16 个,仅前两个循环directly使用6字节的可变密钥字符串,字符串的其余部分是常量。该算法的其余部分是改组和按位运算,这可能需要进行非常重要的进一步优化。每 16 个循环中只有 2 个涉及密钥,那么速度可能会快 8 倍,甚至可能超过 4 倍。
因此,与其说 1024 核 GPU、以 1GHz 运行、提供 1024 哈希/微秒,不如说 4096/微秒或 8096/us = 4-8 哈希/纳秒
大约有 27^6 个密钥 = 387,420,489 个密钥,因此有 md5 哈希值。
387,420,489 个键/4-8/纳秒大约 = 0.05 - 0.1 秒
主机和 GPU 之间的通信会相当慢,但不太可能超过 100%。
所以大约在 0.1 秒到 0.2 秒之间。
md5 哈希值是 16 个字节,因此如果要存储它,将消耗 6.2 GB。在两个现代 GPU 上,每个只需要 2 次传输,但这将是一个非常大的开销。如果哈希值保存到磁盘(即使使用 SSD)或通过 10Gbit 以太网移动,则哈希生成会被 I/O 时间淹没。
只有 94 个可打印 ASCII 字符,因此对于每个 ASCII 6 字符键:
94^6 = 689,869,781,056 个键 / 4-8/纳秒 = 86-172 秒
天啊!-(
长密钥,还有比 MD5 更好的东西!
也许尝试编写一个Python程序来生成最佳的GPU算法?
通过“展开”Python 程序中的循环来生成 GPU“内核”的文本,并打印直线计算的文本,并填充所有常量。
然后尝试找出计算每个密钥长度的 MD5 的最佳指令序列。使用展开的程序,尝试跟踪每个位的操作以及依赖性,然后尝试将这些位及其操作重新组装成连续的 32 位字和新的直线计算。 (公平地说,也许 GPU 编译器无论如何都可以做一些这样的事情?找出答案可能很有趣)