murmur3_128.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package murmur3
  2. import (
  3. "unsafe"
  4. )
  5. const (
  6. c1_128 = 0x87c37b91114253d5
  7. c2_128 = 0x4cf5ad432745937f
  8. size128 = 16
  9. )
  10. // murmur3_128
  11. func murmur3_128(seed uint32, b []byte) (uint64, uint64) {
  12. h1 := uint64(seed)
  13. h2 := uint64(seed)
  14. length := len(b)
  15. h1, h2 = bmix64(b, h1, h2)
  16. // tail
  17. tail := b[length-(length&15):]
  18. var k1, k2 uint64
  19. switch length & 15 {
  20. case 15:
  21. k2 ^= uint64(tail[14]) << 48
  22. fallthrough
  23. case 14:
  24. k2 ^= uint64(tail[13]) << 40
  25. fallthrough
  26. case 13:
  27. k2 ^= uint64(tail[12]) << 32
  28. fallthrough
  29. case 12:
  30. k2 ^= uint64(tail[11]) << 24
  31. fallthrough
  32. case 11:
  33. k2 ^= uint64(tail[10]) << 16
  34. fallthrough
  35. case 10:
  36. k2 ^= uint64(tail[9]) << 8
  37. fallthrough
  38. case 9:
  39. k2 ^= uint64(tail[8]) << 0
  40. k2 *= c2_128
  41. k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
  42. k2 *= c1_128
  43. h2 ^= k2
  44. fallthrough
  45. case 8:
  46. k1 ^= uint64(tail[7]) << 56
  47. fallthrough
  48. case 7:
  49. k1 ^= uint64(tail[6]) << 48
  50. fallthrough
  51. case 6:
  52. k1 ^= uint64(tail[5]) << 40
  53. fallthrough
  54. case 5:
  55. k1 ^= uint64(tail[4]) << 32
  56. fallthrough
  57. case 4:
  58. k1 ^= uint64(tail[3]) << 24
  59. fallthrough
  60. case 3:
  61. k1 ^= uint64(tail[2]) << 16
  62. fallthrough
  63. case 2:
  64. k1 ^= uint64(tail[1]) << 8
  65. fallthrough
  66. case 1:
  67. k1 ^= uint64(tail[0]) << 0
  68. k1 *= c1_128
  69. k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
  70. k1 *= c2_128
  71. h1 ^= k1
  72. }
  73. h1 ^= uint64(length)
  74. h2 ^= uint64(length)
  75. h1 += h2
  76. h2 += h1
  77. h1 = fmix64(h1)
  78. h2 = fmix64(h2)
  79. h1 += h2
  80. h2 += h1
  81. return h1, h2
  82. }
  83. // bmix64 .
  84. func bmix64(b []byte, h1, h2 uint64) (uint64, uint64) {
  85. nblocks := len(b) / 16
  86. // body
  87. for i := 0; i < nblocks; i++ {
  88. t := (*[2]uint64)(unsafe.Pointer(&b[i*16]))
  89. k1, k2 := t[0], t[1]
  90. k1 *= c1_128
  91. k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
  92. k1 *= c2_128
  93. h1 ^= k1
  94. h1 = (h1 << 27) | (h1 >> 37) // rotl64(h1, 27)
  95. h1 += h2
  96. h1 = h1*5 + 0x52dce729
  97. k2 *= c2_128
  98. k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
  99. k2 *= c1_128
  100. h2 ^= k2
  101. h2 = (h2 << 31) | (h2 >> 33) // rotl64(h2, 31)
  102. h2 += h1
  103. h2 = h2*5 + 0x38495ab5
  104. }
  105. return h1, h2
  106. }
  107. // fmix64 .
  108. func fmix64(k uint64) uint64 {
  109. k ^= k >> 33
  110. k *= 0xff51afd7ed558ccd
  111. k ^= k >> 33
  112. k *= 0xc4ceb9fe1a85ec53
  113. k ^= k >> 33
  114. return k
  115. }