来自 Python hash() 函数的正整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18766535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Positive integer from Python hash() function
提问by Craig McQueen
I want to use the Python hash()
function to get integer hashes from objects. But built-in hash()
can give negative values, and I want only positive. And I want it to work sensibly on both 32-bit and 64-bit platforms.
我想使用 Pythonhash()
函数从对象中获取整数哈希。但是内置hash()
可以给出负值,我只想要正值。我希望它在 32 位和 64 位平台上都能正常工作。
I.e. on 32-bit Python, hash()
can return an integer in the range -2**31
to 2**31 - 1
.
On 64-bit systems, hash()
can return an integer in the range -2**63
to 2**63 - 1
.
即在 32 位 Python 上,hash()
可以返回范围-2**31
为的整数2**31 - 1
。在 64 位系统上,hash()
可以返回范围-2**63
为的整数2**63 - 1
。
But I want a hash in the range 0
to 2**32-1
on 32-bit systems, and 0
to 2**64-1
on 64-bit systems.
但我想的范围内的散列0
来2**32-1
在32位系统,以及0
对2**64-1
在64位的系统。
What is the best way to convert the hash value to its equivalent positive value within the range of the 32- or 64-bit target platform?
在 32 位或 64 位目标平台范围内,将哈希值转换为其等效正值的最佳方法是什么?
(Context: I'm trying to make a new random.Random
style class. According to the random.Random.seed()
docs, the seed "optional argument x can be any hashable object." So I'd like to duplicate that functionality, except that my seed algorithm can't handle negative integer values, only positive.)
(上下文:我正在尝试创建一个新的random.Random
样式类。根据random.Random.seed()
文档,种子“可选参数 x 可以是任何可散列的对象。”所以我想复制该功能,除了我的种子算法不能处理负整数值,只有正值。)
采纳答案by falsetru
Using sys.maxsize
:
使用sys.maxsize
:
>>> import sys
>>> sys.maxsize
9223372036854775807L
>>> hash('asdf')
-618826466
>>> hash('asdf') % ((sys.maxsize + 1) * 2)
18446744073090725150L
Alternative using ctypes.c_size_t
:
替代使用ctypes.c_size_t
:
>>> import ctypes
>>> ctypes.c_size_t(hash('asdf')).value
18446744073090725150L
回答by unwind
How about:
怎么样:
h = hash(o)
if h < 0:
h += sys.maxsize
This uses sys.maxsize
to be portable between 32- and 64-bit systems.
这用于sys.maxsize
在 32 位和 64 位系统之间移植。
回答by Voo
Just using sys.maxsize
is wrong for obvious reasons (it being `2*n-1 and not 2*n), but the fix is easy enough:
sys.maxsize
由于显而易见的原因,仅使用是错误的(它是`2* n-1 而不是 2*n),但修复很容易:
h = hash(obj)
h += sys.maxsize + 1
for performance reasons you may want to split the sys.maxsize + 1 into two separate assignments to avoid creating a long integer temporarily for most negative numbers. Although I doubt this is going to matter much
出于性能原因,您可能希望将 sys.maxsize + 1 拆分为两个单独的分配,以避免为大多数负数临时创建长整数。虽然我怀疑这会很重要
回答by Mark Ransom
(Edit: at first I thought you always wanted a 32-bit value)
(编辑:起初我以为你总是想要一个 32 位的值)
Simply AND it with a mask of the desired size. Generally sys.maxsize
will already be such a mask, since it's a power of 2 minus 1.
简单地将它与所需大小的掩码一起使用。通常sys.maxsize
已经是这样的掩码,因为它是 2 减 1 的幂。
import sys
assert (sys.maxsize & (sys.maxsize+1)) == 0 # checks that maxsize+1 is a power of 2
new_hash = hash & sys.maxsize