mirror of
https://github.com/mindoc-org/mindoc.git
synced 2026-02-27 17:03:57 +08:00
59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
// Murmur3 32bit hash function based on
|
|
// http://en.wikipedia.org/wiki/MurmurHash
|
|
package murmur
|
|
|
|
const (
|
|
c1 = 0xcc9e2d51
|
|
c2 = 0x1b873593
|
|
c3 = 0x85ebca6b
|
|
c4 = 0xc2b2ae35
|
|
r1 = 15
|
|
r2 = 13
|
|
m = 5
|
|
n = 0xe6546b64
|
|
)
|
|
|
|
var (
|
|
Seed = uint32(1)
|
|
)
|
|
|
|
func Murmur3(key []byte) (hash uint32) {
|
|
hash = Seed
|
|
iByte := 0
|
|
for ; iByte+4 <= len(key); iByte += 4 {
|
|
k := uint32(key[iByte]) | uint32(key[iByte+1])<<8 | uint32(key[iByte+2])<<16 | uint32(key[iByte+3])<<24
|
|
k *= c1
|
|
k = (k << r1) | (k >> (32 - r1))
|
|
k *= c2
|
|
hash ^= k
|
|
hash = (hash << r2) | (hash >> (32 - r2))
|
|
hash = hash*m + n
|
|
}
|
|
|
|
var remainingBytes uint32
|
|
switch len(key) - iByte {
|
|
case 3:
|
|
remainingBytes += uint32(key[iByte+2]) << 16
|
|
fallthrough
|
|
case 2:
|
|
remainingBytes += uint32(key[iByte+1]) << 8
|
|
fallthrough
|
|
case 1:
|
|
remainingBytes += uint32(key[iByte])
|
|
remainingBytes *= c1
|
|
remainingBytes = (remainingBytes << r1) | (remainingBytes >> (32 - r1))
|
|
remainingBytes = remainingBytes * c2
|
|
hash ^= remainingBytes
|
|
}
|
|
|
|
hash ^= uint32(len(key))
|
|
hash ^= hash >> 16
|
|
hash *= c3
|
|
hash ^= hash >> 13
|
|
hash *= c4
|
|
hash ^= hash >> 16
|
|
|
|
// 出发吧,狗嬷嬷!
|
|
return
|
|
}
|