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

问题描述 投票:1回答:1

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

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

我在Python中有点陌生,我想出了这个丑陋的解决方案(在函数计算中)。为了加快处理速度,我使用执行程序在所有内核上运行此程序。

有人可以帮我弄清楚该函数的“计算”程度如何?如何做得更好?如何遍历我的可变参数数据的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
python sha256
1个回答
0
投票

为了使您的计算功能更具可读性,我建议您更改操作顺序。如果您计算所有字母,然后构建您的字符串,则代码看起来会干净很多,并且更具可读性。作为副产品,它将运行得更快。

当前您正在遵循此顺序

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
© www.soinside.com 2019 - 2024. All rights reserved.