murmur3.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. def murmur3_32(data, seed=0):
  2. """MurmurHash3 was written by Austin Appleby, and is placed in the
  3. public domain. The author hereby disclaims copyright to this source
  4. code."""
  5. c1 = 0xcc9e2d51
  6. c2 = 0x1b873593
  7. length = len(data)
  8. h1 = seed
  9. roundedEnd = (length & 0xfffffffc) # round down to 4 byte block
  10. for i in range(0, roundedEnd, 4):
  11. # little endian load order
  12. k1 = (ord(data[i]) & 0xff) | ((ord(data[i + 1]) & 0xff) << 8) | \
  13. ((ord(data[i + 2]) & 0xff) << 16) | (ord(data[i + 3]) << 24)
  14. k1 *= c1
  15. k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15)
  16. k1 *= c2
  17. h1 ^= k1
  18. h1 = (h1 << 13) | ((h1 & 0xffffffff) >> 19) # ROTL32(h1,13)
  19. h1 = h1 * 5 + 0xe6546b64
  20. # tail
  21. k1 = 0
  22. val = length & 0x03
  23. if val == 3:
  24. k1 = (ord(data[roundedEnd + 2]) & 0xff) << 16
  25. # fallthrough
  26. if val in [2, 3]:
  27. k1 |= (ord(data[roundedEnd + 1]) & 0xff) << 8
  28. # fallthrough
  29. if val in [1, 2, 3]:
  30. k1 |= ord(data[roundedEnd]) & 0xff
  31. k1 *= c1
  32. k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15)
  33. k1 *= c2
  34. h1 ^= k1
  35. # finalization
  36. h1 ^= length
  37. # fmix(h1)
  38. h1 ^= ((h1 & 0xffffffff) >> 16)
  39. h1 *= 0x85ebca6b
  40. h1 ^= ((h1 & 0xffffffff) >> 13)
  41. h1 *= 0xc2b2ae35
  42. h1 ^= ((h1 & 0xffffffff) >> 16)
  43. return h1 & 0xffffffff