基于一些固定数据和其他数据的所有排列,从一些字符串开始计算sha256哈希

时间:2019-11-22 08:16:08

标签: python sha256

我需要计算以某些字符串开头的哈希。 我的输入是:

  1. 其他哈希(固定)
  2. 一些可变参数数据占用5个字节,我需要以某种方式进行准备,以便结果散列以例如“ ABC”

我是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

1 个答案:

答案 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