github.com/spaolacci/murmur3@v1.1.0/murmur32.go (about) 1 package murmur3 2 3 // http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/Murmur3_32HashFunction.java 4 5 import ( 6 "hash" 7 "unsafe" 8 ) 9 10 // Make sure interfaces are correctly implemented. 11 var ( 12 _ hash.Hash = new(digest32) 13 _ hash.Hash32 = new(digest32) 14 _ bmixer = new(digest32) 15 ) 16 17 const ( 18 c1_32 uint32 = 0xcc9e2d51 19 c2_32 uint32 = 0x1b873593 20 ) 21 22 // digest32 represents a partial evaluation of a 32 bites hash. 23 type digest32 struct { 24 digest 25 h1 uint32 // Unfinalized running hash. 26 } 27 28 // New32 returns new 32-bit hasher 29 func New32() hash.Hash32 { return New32WithSeed(0) } 30 31 // New32WithSeed returns new 32-bit hasher set with explicit seed value 32 func New32WithSeed(seed uint32) hash.Hash32 { 33 d := new(digest32) 34 d.seed = seed 35 d.bmixer = d 36 d.Reset() 37 return d 38 } 39 40 func (d *digest32) Size() int { return 4 } 41 42 func (d *digest32) reset() { d.h1 = d.seed } 43 44 func (d *digest32) Sum(b []byte) []byte { 45 h := d.Sum32() 46 return append(b, byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 47 } 48 49 // Digest as many blocks as possible. 50 func (d *digest32) bmix(p []byte) (tail []byte) { 51 h1 := d.h1 52 53 nblocks := len(p) / 4 54 for i := 0; i < nblocks; i++ { 55 k1 := *(*uint32)(unsafe.Pointer(&p[i*4])) 56 57 k1 *= c1_32 58 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 59 k1 *= c2_32 60 61 h1 ^= k1 62 h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) 63 h1 = h1*4 + h1 + 0xe6546b64 64 } 65 d.h1 = h1 66 return p[nblocks*d.Size():] 67 } 68 69 func (d *digest32) Sum32() (h1 uint32) { 70 71 h1 = d.h1 72 73 var k1 uint32 74 switch len(d.tail) & 3 { 75 case 3: 76 k1 ^= uint32(d.tail[2]) << 16 77 fallthrough 78 case 2: 79 k1 ^= uint32(d.tail[1]) << 8 80 fallthrough 81 case 1: 82 k1 ^= uint32(d.tail[0]) 83 k1 *= c1_32 84 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 85 k1 *= c2_32 86 h1 ^= k1 87 } 88 89 h1 ^= uint32(d.clen) 90 91 h1 ^= h1 >> 16 92 h1 *= 0x85ebca6b 93 h1 ^= h1 >> 13 94 h1 *= 0xc2b2ae35 95 h1 ^= h1 >> 16 96 97 return h1 98 } 99 100 /* 101 func rotl32(x uint32, r byte) uint32 { 102 return (x << r) | (x >> (32 - r)) 103 } 104 */ 105 106 // Sum32 returns the MurmurHash3 sum of data. It is equivalent to the 107 // following sequence (without the extra burden and the extra allocation): 108 // hasher := New32() 109 // hasher.Write(data) 110 // return hasher.Sum32() 111 func Sum32(data []byte) uint32 { return Sum32WithSeed(data, 0) } 112 113 // Sum32WithSeed returns the MurmurHash3 sum of data. It is equivalent to the 114 // following sequence (without the extra burden and the extra allocation): 115 // hasher := New32WithSeed(seed) 116 // hasher.Write(data) 117 // return hasher.Sum32() 118 func Sum32WithSeed(data []byte, seed uint32) uint32 { 119 120 h1 := seed 121 122 nblocks := len(data) / 4 123 var p uintptr 124 if len(data) > 0 { 125 p = uintptr(unsafe.Pointer(&data[0])) 126 } 127 p1 := p + uintptr(4*nblocks) 128 for ; p < p1; p += 4 { 129 k1 := *(*uint32)(unsafe.Pointer(p)) 130 131 k1 *= c1_32 132 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 133 k1 *= c2_32 134 135 h1 ^= k1 136 h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) 137 h1 = h1*4 + h1 + 0xe6546b64 138 } 139 140 tail := data[nblocks*4:] 141 142 var k1 uint32 143 switch len(tail) & 3 { 144 case 3: 145 k1 ^= uint32(tail[2]) << 16 146 fallthrough 147 case 2: 148 k1 ^= uint32(tail[1]) << 8 149 fallthrough 150 case 1: 151 k1 ^= uint32(tail[0]) 152 k1 *= c1_32 153 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 154 k1 *= c2_32 155 h1 ^= k1 156 } 157 158 h1 ^= uint32(len(data)) 159 160 h1 ^= h1 >> 16 161 h1 *= 0x85ebca6b 162 h1 ^= h1 >> 13 163 h1 *= 0xc2b2ae35 164 h1 ^= h1 >> 16 165 166 return h1 167 }