murmur128.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package murmur3
  2. import (
  3. //"encoding/binary"
  4. "hash"
  5. "unsafe"
  6. )
  7. const (
  8. c1_128 = 0x87c37b91114253d5
  9. c2_128 = 0x4cf5ad432745937f
  10. )
  11. // Make sure interfaces are correctly implemented.
  12. var (
  13. _ hash.Hash = new(digest128)
  14. _ Hash128 = new(digest128)
  15. _ bmixer = new(digest128)
  16. )
  17. // Hash128 represents a 128-bit hasher
  18. // Hack: the standard api doesn't define any Hash128 interface.
  19. type Hash128 interface {
  20. hash.Hash
  21. Sum128() (uint64, uint64)
  22. }
  23. // digest128 represents a partial evaluation of a 128 bites hash.
  24. type digest128 struct {
  25. digest
  26. h1 uint64 // Unfinalized running hash part 1.
  27. h2 uint64 // Unfinalized running hash part 2.
  28. }
  29. // New128 returns a 128-bit hasher
  30. func New128() Hash128 { return New128WithSeed(0) }
  31. // New128WithSeed returns a 128-bit hasher set with explicit seed value
  32. func New128WithSeed(seed uint32) Hash128 {
  33. d := new(digest128)
  34. d.seed = seed
  35. d.bmixer = d
  36. d.Reset()
  37. return d
  38. }
  39. func (d *digest128) Size() int { return 16 }
  40. func (d *digest128) reset() { d.h1, d.h2 = uint64(d.seed), uint64(d.seed) }
  41. func (d *digest128) Sum(b []byte) []byte {
  42. h1, h2 := d.Sum128()
  43. return append(b,
  44. byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32),
  45. byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1),
  46. byte(h2>>56), byte(h2>>48), byte(h2>>40), byte(h2>>32),
  47. byte(h2>>24), byte(h2>>16), byte(h2>>8), byte(h2),
  48. )
  49. }
  50. func (d *digest128) bmix(p []byte) (tail []byte) {
  51. h1, h2 := d.h1, d.h2
  52. nblocks := len(p) / 16
  53. for i := 0; i < nblocks; i++ {
  54. t := (*[2]uint64)(unsafe.Pointer(&p[i*16]))
  55. k1, k2 := t[0], t[1]
  56. k1 *= c1_128
  57. k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
  58. k1 *= c2_128
  59. h1 ^= k1
  60. h1 = (h1 << 27) | (h1 >> 37) // rotl64(h1, 27)
  61. h1 += h2
  62. h1 = h1*5 + 0x52dce729
  63. k2 *= c2_128
  64. k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
  65. k2 *= c1_128
  66. h2 ^= k2
  67. h2 = (h2 << 31) | (h2 >> 33) // rotl64(h2, 31)
  68. h2 += h1
  69. h2 = h2*5 + 0x38495ab5
  70. }
  71. d.h1, d.h2 = h1, h2
  72. return p[nblocks*d.Size():]
  73. }
  74. func (d *digest128) Sum128() (h1, h2 uint64) {
  75. h1, h2 = d.h1, d.h2
  76. var k1, k2 uint64
  77. switch len(d.tail) & 15 {
  78. case 15:
  79. k2 ^= uint64(d.tail[14]) << 48
  80. fallthrough
  81. case 14:
  82. k2 ^= uint64(d.tail[13]) << 40
  83. fallthrough
  84. case 13:
  85. k2 ^= uint64(d.tail[12]) << 32
  86. fallthrough
  87. case 12:
  88. k2 ^= uint64(d.tail[11]) << 24
  89. fallthrough
  90. case 11:
  91. k2 ^= uint64(d.tail[10]) << 16
  92. fallthrough
  93. case 10:
  94. k2 ^= uint64(d.tail[9]) << 8
  95. fallthrough
  96. case 9:
  97. k2 ^= uint64(d.tail[8]) << 0
  98. k2 *= c2_128
  99. k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
  100. k2 *= c1_128
  101. h2 ^= k2
  102. fallthrough
  103. case 8:
  104. k1 ^= uint64(d.tail[7]) << 56
  105. fallthrough
  106. case 7:
  107. k1 ^= uint64(d.tail[6]) << 48
  108. fallthrough
  109. case 6:
  110. k1 ^= uint64(d.tail[5]) << 40
  111. fallthrough
  112. case 5:
  113. k1 ^= uint64(d.tail[4]) << 32
  114. fallthrough
  115. case 4:
  116. k1 ^= uint64(d.tail[3]) << 24
  117. fallthrough
  118. case 3:
  119. k1 ^= uint64(d.tail[2]) << 16
  120. fallthrough
  121. case 2:
  122. k1 ^= uint64(d.tail[1]) << 8
  123. fallthrough
  124. case 1:
  125. k1 ^= uint64(d.tail[0]) << 0
  126. k1 *= c1_128
  127. k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
  128. k1 *= c2_128
  129. h1 ^= k1
  130. }
  131. h1 ^= uint64(d.clen)
  132. h2 ^= uint64(d.clen)
  133. h1 += h2
  134. h2 += h1
  135. h1 = fmix64(h1)
  136. h2 = fmix64(h2)
  137. h1 += h2
  138. h2 += h1
  139. return h1, h2
  140. }
  141. func fmix64(k uint64) uint64 {
  142. k ^= k >> 33
  143. k *= 0xff51afd7ed558ccd
  144. k ^= k >> 33
  145. k *= 0xc4ceb9fe1a85ec53
  146. k ^= k >> 33
  147. return k
  148. }
  149. /*
  150. func rotl64(x uint64, r byte) uint64 {
  151. return (x << r) | (x >> (64 - r))
  152. }
  153. */
  154. // Sum128 returns the MurmurHash3 sum of data. It is equivalent to the
  155. // following sequence (without the extra burden and the extra allocation):
  156. // hasher := New128()
  157. // hasher.Write(data)
  158. // return hasher.Sum128()
  159. func Sum128(data []byte) (h1 uint64, h2 uint64) { return Sum128WithSeed(data, 0) }
  160. // Sum128WithSeed returns the MurmurHash3 sum of data. It is equivalent to the
  161. // following sequence (without the extra burden and the extra allocation):
  162. // hasher := New128WithSeed(seed)
  163. // hasher.Write(data)
  164. // return hasher.Sum128()
  165. func Sum128WithSeed(data []byte, seed uint32) (h1 uint64, h2 uint64) {
  166. d := &digest128{h1: uint64(seed), h2: uint64(seed)}
  167. d.seed = seed
  168. d.tail = d.bmix(data)
  169. d.clen = len(data)
  170. return d.Sum128()
  171. }