wim*_*wim 3 python hash bit-manipulation bit-shift
出于好奇,我看到了将对象的 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 Code Online (Sandbox Code Playgroud)
但是正如您在下面看到的,下面的函数有时不正确。我错过了什么?
>>> 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
Run Code Online (Sandbox Code Playgroud)
散列产生一个有符号整数,您的代码产生一个无符号整数。
对于您的第一个错误结果,该id(a)值为4357309288; 那是000000000000000000000000000000010000001110110111010000110110100064 位。最后 4 位是1000,将它们移到开头给出了 的二进制值1000000000000000000000000000000000010000001110110111010000110110,--9223372036582443978当解释为2 的补码有符号整数时,这是因为第一个位,即符号位,被设置为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
Run Code Online (Sandbox Code Playgroud)
在.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
Run Code Online (Sandbox Code Playgroud)
如果您想坚持使用标准库,请使用此 Stack Overflow 答案来获取一个twos_comp()函数:
>>> twos_comp(9223372037127107638, 64)
-9223372036582443978L
Run Code Online (Sandbox Code Playgroud)
您的功能将是:
def my_hash(a):
bits = format(id(a), '064b')
rot4 = bits[-4:] + bits[:-4]
n = twos_comp(int(rot4, 2), 64)
return n
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2211 次 |
| 最近记录: |