'''
N = 2097152
0.0455327033996582
0.9995155334472656
0.9995260238647461
0.9997577667236328
起因是做推箱子游戏,想把箱子们的坐标hash下。如6个箱子,每个的x和y
都是0~31(一个字节有10位就好了)。上面的数越大,hash越接近perfect.
CRC32肯定慢。
'''
from random import randint
from zlib import crc32
N = 1 << 21; L = 12; s = [set(), set(), set(), set()]
def mine():
h = v[0]
for i in range(1, L): h ^= (v[i] << i)
return h & 0x7FFFFFFF
def SDBMHash():
h = 0
# hash = 65599 * hash + *v++; 65599 = 65536 + 64 - 1
for x in v: t = h << 6; h = (t << 10) + t - h + x
return h & 0x7FFFFFFF
def JSHash():
h = 1315423911 # nearly a prime. 1315423911 = 3 * 438474637
for x in v: h ^= (h << 5) + x + (h >> 2)
return h & 0x7FFFFFFF
v = L * [0]
for i in range(N):
for j in range(L): v[j] = randint(1, 32)
s[0].add(mine())
s[1].add(SDBMHash())
s[2].add(JSHash())
s[3].add(crc32(bytes(v)))
print(f'{N = }')
for i in range(len(s)): print(len(s[i]) / N)