2013-03-26 115 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具有相同的位數,就可以預先計算的面具,它存儲爲一個模塊級的「常數」。

相關問題