我需要计算以某些字符串开头的哈希。 我的输入是:
我是Python的新手,我想出了这个丑陋的解决方案(在函数calculate中)。为了加快处理速度,我使用执行程序在所有内核上运行该程序。
有人可以帮助我弄清楚该函数的“计算”程度吗?如何做得更好?如何遍历我的可变参数数据的5个字节的所有排列?最后,在这里我该怎么做是错误的还是非Python的?
import hashlib
import concurrent.futures
import copy
input_hash = [0x79,0xaf,0x37,0xc4,0x32,0x8e,0x7b,0x67,0xb1,0xfa,0x76,0x36,0x11,0x21,0xa4,0xdd,0x6c,0x29,0xf0,0x6b,0x50,0x67,0x57,0x16,0x0b,0xee,0x30,0x32,0x2a,0x05,0x9e,0x75]
def calculate(pars):
print(pars)
for x in range(pars[0],pars[1]):
whole = []
whole.extend(bytearray(input_hash))
whole.extend(bytes([x]))
copy1 = copy.deepcopy(whole)
for y in range(256):
whole = copy.deepcopy(copy1)
whole.extend(bytes([y]))
copy2 = copy.deepcopy(whole)
for z in range(256):
whole = copy.deepcopy(copy2)
whole.extend(bytes([z]))
copy3 = copy.deepcopy(whole)
for a in range(256):
whole = copy.deepcopy(copy3)
whole.extend(bytes([a]))
copy4 = copy.deepcopy(whole)
for b in range(256):
whole = copy.deepcopy(copy4)
whole.extend(bytes([b]))
whole.extend(bytes([0]*2))
m = hashlib.sha256()
m.update(bytearray(whole))
d = m.hexdigest()
if d.startswith('ABC'):
print('success!, x = %, y = %, z = %, a = %, b = %' % x, y, z, a, b)
return
data = [(0,33),(33,67),(67,101),(101,135),(135,169),(169,203),(203,237),(237,256)]
with concurrent.futures.ProcessPoolExecutor() as executor:
res = executor.map(calculate, data)
for r in res:
pass
答案 0 :(得分:1)
为了使您的计算功能更具可读性,我建议更改您执行操作的顺序。
如果您计算所有字母,然后构建您的字符串,则代码看起来会干净很多,并且
更具可读性。作为副产品,它将运行得更快。
当前您正在按照此顺序
make string,
append salt
1
copy string
calculate next letter
append letter to string
2
copy string
calculate next letter
append letter to string
repeat 3 more time.
hash string and compare value
如果您看起来更干净
1
calculate next letter
calculate next letter
calculate next letter
......
make string
append salt
append letters
hash string and compare value
我遵循一个简单的规则, 如果我必须多次编写相同的指令,那 一种简化程序的方法
您的print()
语句在尝试时会引发错误。
我相信您想显示十六进制结果。您将需要这样的东西
print('success!, x = %02x, y = %02x, z = %02x, a = %02x, b = %02x' % (x, y, z, a, b))
还有许多其他格式化字符串Some can be found here.
的方法您已使用8个值对数组data[]
进行了硬编码,并在其中添加了一个for-range循环
calculate()
功能可帮助分散CPU核心的工作量。这限制了您的代码
最多可在8个内核上运行。
我可以建议让ProcessPoolExecutor().map
为您做这件事。它将使更多
有效使用各种硬件设置,而无需了解系统。
在calculate()
函数中,将for x in range(pars[0],pars[1]):
替换为x = pars
并纠正缩进,然后在致电executor.map
时使用range()
,
res = executor.map(calculate, range(256))
它将通过每个进程1次迭代,直到全部完成。 More information about executor.map can be found here.
以下是具有上述更改的代码
import hashlib
import concurrent.futures
input_hash = [0x79,0xaf,0x37,0xc4,0x32,0x8e,0x7b,0x67,0xb1,0xfa,0x76,0x36,0x11,0x21,0xa4,0xdd,0x6c,0x29,0xf0,0x6b,0x50,0x67,0x57,0x16,0x0b,0xee,0x30,0x32,0x2a,0x05,0x9e,0x75]
def calculate(pars):
print(pars)
x = pars
for y in range(256):
for z in range(256):
for a in range(256):
for b in range(256):
whole = []
whole.extend(bytearray(input_hash))
whole.extend(bytes([x]))
whole.extend(bytes([y]))
whole.extend(bytes([z]))
whole.extend(bytes([a]))
whole.extend(bytes([b]))
whole.extend(bytes([0]*2))
m = hashlib.sha256()
m.update(bytearray(whole))
d = m.hexdigest()
if d.startswith('ABC'):
print('success!, x = %02x, y = %02x, z = %02x, a = %02x, b = %02x' % (x, y, z, a, b))
return
with concurrent.futures.ProcessPoolExecutor() as executor:
res = executor.map(calculate, range(256))
for r in res:
pass