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.
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
.
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.
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?
(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.)
Just using
sys.maxsize
is wrong for obvious reasons (it being `2*n-1 and not 2*n), but the fix is easy enough: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
(Edit: at first I thought you always wanted a 32-bit value)
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.Using
sys.maxsize
:Alternative using
ctypes.c_size_t
:How about:
This uses
sys.maxsize
to be portable between 32- and 64-bit systems.