0

我正在寻找比较 Python3 中的哈希位,作为 Hashcash 系统的一部分。例如,我想知道 SHA256 哈希的前 N ​​位是否为 0。

现在,我正在根据十六进制版本执行此操作

  if newhash.hexdigest()[0:4] == '0000'

但这并不能让我像我想要的那样精细——我更愿意比较原始位,这让我可以更接近地改变匹配 0 的数量。

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

  bin(int(h.hexdigest(), 16))[2:]

但这似乎不可能是最快/正确的方法。

对于正确/正确的方法,我将不胜感激;)

谢谢,

-CPD

4

3 回答 3

1

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

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

如果您继续test_bits使用相同的位数调用,您可以预先计算掩码并将其存储为模块级“常量”。

于 2013-03-26T19:35:27.707 回答
0

您可以像这样解压缩摘要的前 8 个字节:

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

但我不确定它是否更快,并且对其余部分不方便。在 Python 中进行位旋转并不容易。

于 2013-03-26T16:07:28.757 回答
0

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

>>> x=gmpy2.mpz(12345)
>>> x.digits(2)
'11000000111001'
>>> x[2:5].digits(2)
'110'

如果您需要修改单个位,gmpy2 包含一个可变整数类型,允许您就地修改位。

免责声明:我维护 gmpy2。

于 2013-03-26T16:11:05.697 回答