来自Python hash()函数的正整数

kkbh8khc  于 2022-12-17  发布在  Python
关注(0)|答案(5)|浏览(171)

我想使用Python的hash()函数从对象中获取整数哈希值,但是内置的hash()函数可以给予负值,我只想得到正值,而且我想让它在32位和64位平台上都能正常工作。
例如,在32位Python上,hash()可以返回-2**312**31 - 1范围内的整数;在64位系统上,hash()可以返回-2**632**63 - 1范围内的整数。
但我希望哈希值在32位系统上介于02**32-1之间,在64位系统上介于02**64-1之间。
在32位或64位目标平台的范围内,将哈希值转换为其等效正值的最佳方法是什么?
(上下文:我正在尝试创建一个新的random.Random样式类。根据random.Random.seed()文档,seed“可选参数x可以是任何可散列对象。”所以我想复制该功能,只是我的seed算法不能处理负整数值,只能处理正整数值。)

oyxsuwqo

oyxsuwqo1#

仅仅使用sys.maxsize是错误的,原因很明显(它是'2n-1而不是2n),但修复起来很容易:

h = hash(obj)
h += sys.maxsize + 1

出于性能方面的考虑,您可能希望将sys.maxsize + 1拆分为两个独立的赋值,以避免为大多数负数临时创建一个长整数。

jckbn6z7

jckbn6z72#

(Edit:一开始我以为你一直想要一个32位的值)
简单地将其与所需大小的掩码进行AND运算,通常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
hs1ihplo

hs1ihplo3#

不如这样:

h = hash(o)
if h < 0:
  h += sys.maxsize

它使用sys.maxsize在32位和64位系统之间移植。

uemypmqf

uemypmqf4#

import sys

# Calculate the maximum positive integer value for the target platform
max_int = 2**(sys.maxsize.bit_length() - 1) - 1

# Calculate the positive integer hash value within the range of the target platform
hash_value = hash(obj) % max_int

表达式**2**(sys.maxsize.bit_length() - 1) - 1**用于计算目标平台的最大正整数值。

**sys.maxsize变量包含平台的最大可能整数的最大值。bit_length()方法返回以二进制表示整数所需的位数,- 1用于说明符号位(不包括在maxsize**值中)。

例如,在32位系统上,**sys.maxsize的值为2147483647,这是32位有符号整数的最大值。bit_length()方法返回32,而- 1给出的结果为31。表达式2**31 - 1计算32位平台的最大正整数值。号码是2147483647。
在64位系统上,
sys.maxsize的值为9223372036854775807,这是64位有符号整数的最大值。bit_length()方法返回64,- 1给出的结果为63。表达式2**63 - 1**计算64位平台的最大正整数值。号码是9223372036854775807。
此表达式可用于计算任何平台的最大正整数值,而不考虑位数。

r7xajy2e

r7xajy2e5#

使用sys.maxsize

>>> import sys
>>> sys.maxsize
9223372036854775807L
>>> hash('asdf')
-618826466
>>> hash('asdf') % ((sys.maxsize + 1) * 2)
18446744073090725150L

使用ctypes.c_size_t的替代方法:

>>> import ctypes
>>> ctypes.c_size_t(hash('asdf')).value
18446744073090725150L

相关问题