什么';在Python3中比较散列数据位的最快方法是什么?

什么';在Python3中比较散列数据位的最快方法是什么?,python,hash,python-3.x,binary,hashlib,Python,Hash,Python 3.x,Binary,Hashlib,作为Hashcash系统的一部分,我希望比较Python3中的散列数据。 例如,我想知道SHA256散列的前N位是否为0 现在,我是根据十六进制版本来做这件事的 if newhash.hexdigest()[0:4] == '0000' 但这并不能让我像我想要的那样精确-我更喜欢比较原始位,这让我可以更精确地改变匹配0的数量 我通过一个复杂的跃点得到要比较的位值 bin(int(h.hexdigest(), 16))[2:] 但这似乎不可能是最快/正确的方法 如能就正确/正确的方法提

作为Hashcash系统的一部分,我希望比较Python3中的散列数据。 例如,我想知道SHA256散列的前N位是否为0

现在,我是根据十六进制版本来做这件事的

  if newhash.hexdigest()[0:4] == '0000'
但这并不能让我像我想要的那样精确-我更喜欢比较原始位,这让我可以更精确地改变匹配0的数量

我通过一个复杂的跃点得到要比较的位值

  bin(int(h.hexdigest(), 16))[2:]
但这似乎不可能是最快/正确的方法

如能就正确/正确的方法提出建议,我将不胜感激;)

谢谢


-CPD

您可以按如下方式解压缩摘要的前8个字节:

bin(struct.unpack('>Q', h.digest()[:8])[0])

但我不确定它是否更快,而且对于其他部分来说也不方便。在Python中,位旋转并不容易。

如果可以从右侧处理索引位,则中的整数类型支持切片以访问单个位:

>>> x=gmpy2.mpz(12345)
>>> x.digits(2)
'11000000111001'
>>> x[2:5].digits(2)
'110'
如果需要修改单个位,gmpy2包含一个可变整数类型,允许您就地修改位


免责声明:我维护gmpy2。

要检查数字的选定位是否为零,您需要使用设置了所有这些位的预计算掩码输入数字,并将结果与零进行比较。检查
m
位编号的第一个
n
位的掩码是由
n
1s和
m-n
0s组成的二进制数字

def mask(n, m):
    return ((1 << n) - 1) << (m - n)

def test_0bits(digest_bytes, n_bits):
    m = 8 * len(digest_bytes)
    digest_num = int.from_bytes(digest_bytes, 'big')
    return digest_num & mask(n_bits, m) == 0

>>> test_0bits(b'\123\456', 3)  # 001 010 011 100 101 110
False
>>> test_0bits(b'\023\456', 3)  # 000 010 011 100 101 110
True
def掩码(n,m):
返回((1>测试0位(b'\123\456',3)#001 010 011 100 101 110
假的
>>>测试位(b'\023\456',3)#000 010 011 100 101 110
真的
如果您继续使用相同的位数调用
test_bits
,则可以预计算掩码并将其存储为模块级“常量”。

通常可以相对于位比较优化前导零()的计数。