"""SipHash — SipHash-2-4 implementation. Ported from net.i2p.util.SipHash / net.i2p.crypto.SipHashInline. Fast non-cryptographic hash for hash tables. """ import os import struct def _rotl64(v: int, n: int) -> int: return ((v << n) | (v >> (64 - n))) & 0xFFFFFFFFFFFFFFFF def _sip_round(v0: int, v1: int, v2: int, v3: int): v0 = (v0 + v1) & 0xFFFFFFFFFFFFFFFF v1 = _rotl64(v1, 13) v1 ^= v0 v0 = _rotl64(v0, 32) v2 = (v2 + v3) & 0xFFFFFFFFFFFFFFFF v3 = _rotl64(v3, 16) v3 ^= v2 v0 = (v0 + v3) & 0xFFFFFFFFFFFFFFFF v3 = _rotl64(v3, 21) v3 ^= v0 v2 = (v2 + v1) & 0xFFFFFFFFFFFFFFFF v1 = _rotl64(v1, 17) v1 ^= v2 v2 = _rotl64(v2, 32) return v0, v1, v2, v3 # Per-process random keys (like Java's per-JVM constants) _K0 = struct.unpack(" int: """Compute SipHash-2-4 digest. Returns a 64-bit integer.""" if length < 0: length = len(data) - offset return SipHash._siphash24(_K0, _K1, data, offset, length) @staticmethod def hash_code(data: bytes | None) -> int: """Compute a 32-bit hash code from SipHash-2-4.""" if data is None: return 0 h = SipHash.digest(data) return h & 0xFFFFFFFF @staticmethod def _siphash24(k0: int, k1: int, data: bytes, off: int, length: int) -> int: v0 = k0 ^ 0x736F6D6570736575 v1 = k1 ^ 0x646F72616E646F6D v2 = k0 ^ 0x6C7967656E657261 v3 = k1 ^ 0x7465646279746573 # Process 8-byte blocks end = off + (length & ~7) for i in range(off, end, 8): m = struct.unpack_from("= 7: b |= data[tail_off + 6] << 48 if remaining >= 6: b |= data[tail_off + 5] << 40 if remaining >= 5: b |= data[tail_off + 4] << 32 if remaining >= 4: b |= data[tail_off + 3] << 24 if remaining >= 3: b |= data[tail_off + 2] << 16 if remaining >= 2: b |= data[tail_off + 1] << 8 if remaining >= 1: b |= data[tail_off] v3 ^= b v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) v0 ^= b # Finalization v2 ^= 0xFF v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) v0, v1, v2, v3 = _sip_round(v0, v1, v2, v3) return (v0 ^ v1 ^ v2 ^ v3) & 0xFFFFFFFFFFFFFFFF