Skip to content

Instantly share code, notes, and snippets.

@pszemraj
Created November 18, 2024 16:38
Show Gist options
  • Save pszemraj/4f4bc12d2c543e185de6543efdb1646c to your computer and use it in GitHub Desktop.
Save pszemraj/4f4bc12d2c543e185de6543efdb1646c to your computer and use it in GitHub Desktop.
Compute the 64-bit hash of the input bytes object using the chibihash64 algorithm.
def chibihash64__load64le(p, offset=0):
"""Load 8 bytes from the input bytes object as a little-endian 64-bit integer."""
return int.from_bytes(p[offset : offset + 8], "little", signed=False)
def chibihash64(key, seed=0):
"""
Compute the 64-bit hash of the input bytes object using the chibihash64 algorithm.
Parameters:
key (bytes): The input data to hash.
seed (int): An optional seed value for the hash function.
Returns:
int: The 64-bit hash value.
"""
k = key
l = len(k)
P1 = 0x2B7E151628AED2A5
P2 = 0x9E3793492EEDC3F7
P3 = 0x3243F6A8885A308D
h = [P1, P2, P3, seed & 0xFFFFFFFFFFFFFFFF]
pos = 0
while l - pos >= 32:
for i in range(4):
lane = chibihash64__load64le(k, pos)
h[i] ^= lane
h[i] = (h[i] * P1) & 0xFFFFFFFFFFFFFFFF
h[(i + 1) & 3] ^= ((lane << 40) | (lane >> 24)) & 0xFFFFFFFFFFFFFFFF
pos += 8
h[0] = (h[0] + ((l << 32) | (l >> 32))) & 0xFFFFFFFFFFFFFFFF
if (l - pos) & 1:
h[0] ^= k[pos]
pos += 1
h[0] = (h[0] * P2) & 0xFFFFFFFFFFFFFFFF
h[0] ^= h[0] >> 31
i = 1
while l - pos >= 8:
h[i] ^= chibihash64__load64le(k, pos)
h[i] = (h[i] * P2) & 0xFFFFFFFFFFFFFFFF
h[i] ^= h[i] >> 31
pos += 8
i += 1
i = 0
while l - pos > 0:
b0 = k[pos]
b1 = k[pos + 1] if pos + 1 < l else 0
val = b0 | (b1 << 8)
h[i] ^= val
h[i] = (h[i] * P3) & 0xFFFFFFFFFFFFFFFF
h[i] ^= h[i] >> 31
pos += 2
i += 1
x = seed & 0xFFFFFFFFFFFFFFFF
x ^= (h[0] * ((h[2] >> 32) | 1)) & 0xFFFFFFFFFFFFFFFF
x ^= (h[1] * ((h[3] >> 32) | 1)) & 0xFFFFFFFFFFFFFFFF
x ^= (h[2] * ((h[0] >> 32) | 1)) & 0xFFFFFFFFFFFFFFFF
x ^= (h[3] * ((h[1] >> 32) | 1)) & 0xFFFFFFFFFFFFFFFF
x &= 0xFFFFFFFFFFFFFFFF
# moremur mixing function
x ^= x >> 27
x = (x * 0x3C79AC492BA7B653) & 0xFFFFFFFFFFFFFFFF
x ^= x >> 33
x = (x * 0x1C69B3F74AC4AE35) & 0xFFFFFFFFFFFFFFFF
x ^= x >> 27
return x & 0xFFFFFFFFFFFFFFFF
def chibihash64_hexdigest(key, seed=0):
"""
Compute the 64-bit hash of the input bytes object and return it as a hexadecimal string.
Parameters:
key (bytes): The input data to hash.
seed (int): An optional seed value for the hash function.
Returns:
str: The 64-bit hash value as a 16-character hexadecimal string.
"""
hash_value = chibihash64(key, seed)
return f"{hash_value:016x}"
if __name__ == "__main__":
data = b"hello world"
seed = 0
hex_hash = chibihash64_hexdigest(data, seed)
print(f"Hex digest: {hex_hash}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment