2013-03-26 116 views
0

我正在寻找比较Python3中散列的位,作为Hashcash系统的一部分。 因此,举例来说,我想知道,如果一个SHA256散列的前N位为0比较Python3中散列位的最快方法是什么?

现在,我基于十六进制版本

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

这样做,但这种不让我尽可能细化 - 我宁愿比较原始位,这让我可以更密切地改变匹配0的数量。

我得到得到的位值通过一个令人费解的跳

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

比较但这似乎像它不可能是做最快/正道。

我会很感激的权利/正确的方法去做任何意见;)

感谢,

-CPD

+0

计数前导零([找到最重要的位集](http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious))可以相对于一般比特比较进行优化。 – jfs 2013-03-26 18:01:03

回答

0

可以拿到前8个字节摘要的解压这样:

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

但我不确定它是否更快,并且对其余位不太方便。在Python中使用Bit-twiddling并不容易。

0

如果你能处理从右边索引位,gmpy2整数类型支持切片中访问各个位:如果您需要修改个别位

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

,gmpy2包括一个可变的整数类型,允许你要修改这些位。

声明:我维护gmpy2。

1

要检查一些选择的比特是零,你需要预先计算面具具有所有这些设置位and的数量,比较的结果为零。检查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 

如果你不断的打电话test_bits具有相同的位数,就可以预先计算的面具,它存储为一个模块级的“常数”。

相关问题