[英]Rotate bits in python
出於好奇,我看到了在字符串域中將對象的id轉換為其哈希的操作,而不是像^
, |
這樣的常規按位操作|
, &
~
。
class A:
pass
def my_hash(a):
bits = format(id(a), '064b')
rot4 = bits[-4:] + bits[:-4]
n = int(rot4, 2)
return n
for _ in xrange(10):
a = A()
print hash(a) == my_hash(a), hash(a), my_hash(a)
但是正如您在下面看到的那樣,下面的功能有時是不正確的。 我想念什么?
>>> run /tmp/thing.py
True 272331835 272331835
False -9223372036582443978 9223372037127107638
True 272331835 272331835
False -9223372036582443978 9223372037127107638
True 272331835 272331835
False -9223372036582443978 9223372037127107638
True 272331835 272331835
False -9223372036582443978 9223372037127107638
True 272331835 272331835
False -9223372036582443978 9223372037127107638
哈希產生一個有符號的整數,您的代碼產生一個無符號的整數。
對於第一個不正確的結果, id(a)
值為4357309288
; 這是0000000000000000000000000000000100000011101101110100001101101000
(64位)。 最后4位為1000
,將其移到開頭將給出二進制值1000000000000000000000000000000000010000001110110111010000110110
,當將其解釋為2的補碼有符號整數時為--9223372036582443978
,因為該位的第一個位(符號位)設置為1
。
另一方面, int(rot4, 2)
始終將輸入解釋為無符號 ,長度無限的整數,因此您將獲得9223372037127107638
。
Python沒有任何“簡單”選項來將包含二進制數字的字符串解釋為帶符號的整數,您可以使用bitstring
庫來簡化操作:
>>> from bitstring import Bits
>>> bits = Bits(int=4357309288, length=64)
>>> bits[-4:]
Bits('0x8')
>>> bits[-4:] + bits[:-4]
Bits('0x80000000103b7436')
>>> (bits[-4:] + bits[:-4]).int
-9223372036582443978L
>>> (bits[-4:] + bits[:-4]).uint
9223372037127107638L
.int
和.uint
為您提供有符號和無符號整數解釋。
使用位bitstring
我得到正確的輸出:
>>> def my_hash(a):
... bits = Bits(int=id(a), length=64)
... return (bits[-4:] + bits[:-4]).int
...
>>> for _ in xrange(10):
... a = A()
... print hash(a) == my_hash(a), hash(a), my_hash(a)
...
True -9223372036585854145 -9223372036585854145
True 268921659 268921659
True -9223372036585854145 -9223372036585854145
True 268921659 268921659
True -9223372036585854145 -9223372036585854145
True 268921659 268921659
True -9223372036585854145 -9223372036585854145
True 268921659 268921659
True -9223372036585854145 -9223372036585854145
True 268921659 268921659
如果您想堅持使用標准庫,請使用此Stack Overflow答案來獲取一個twos_comp()
函數:
>>> twos_comp(9223372037127107638, 64)
-9223372036582443978L
那么您的功能將是:
def my_hash(a):
bits = format(id(a), '064b')
rot4 = bits[-4:] + bits[:-4]
n = twos_comp(int(rot4, 2), 64)
return n
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.