dvc890's picture
Upload 42 files
581b6d4 verified
package funcaptcha
import (
"encoding/binary"
"fmt"
)
type digest struct {
h1, h2 uint64
length int
seed uint64
}
func getMurmur128String(input string, seed uint64) string {
d := newWithSeed(seed)
d.Write([]byte(input))
h1, h2 := d.Sum()
return fmt.Sprintf("%016x%016x", h1, h2)
}
func newWithSeed(seed uint64) *digest {
d := new(digest)
d.seed = seed
d.h1 = seed
d.h2 = seed
return d
}
func (d *digest) Write(data []byte) {
length := len(data)
d.length += length
var (
h1 = d.h1
h2 = d.h2
c1 = uint64(0x87c37b91114253d5)
c2 = uint64(0x4cf5ad432745937f)
)
for len(data) >= 16 {
k1 := binary.LittleEndian.Uint64(data)
k2 := binary.LittleEndian.Uint64(data[8:])
k1 *= c1
k1 = (k1 << 31) | (k1 >> (64 - 31))
k1 *= c2
h1 ^= k1
h1 = (h1 << 27) | (h1 >> (64 - 27))
h1 += h2
h1 = h1*5 + 0x52dce729
k2 *= c2
k2 = (k2 << 33) | (k2 >> (64 - 33))
k2 *= c1
h2 ^= k2
h2 = (h2 << 31) | (h2 >> (64 - 31))
h2 += h1
h2 = h2*5 + 0x38495ab5
data = data[16:]
}
var k1, k2 uint64
switch len(data) {
case 15:
k2 ^= uint64(data[14]) << 48
fallthrough
case 14:
k2 ^= uint64(data[13]) << 40
fallthrough
case 13:
k2 ^= uint64(data[12]) << 32
fallthrough
case 12:
k2 ^= uint64(data[11]) << 24
fallthrough
case 11:
k2 ^= uint64(data[10]) << 16
fallthrough
case 10:
k2 ^= uint64(data[9]) << 8
fallthrough
case 9:
k2 ^= uint64(data[8])
k2 *= c2
k2 = (k2 << 33) | (k2 >> (64 - 33))
k2 *= c1
h2 ^= k2
fallthrough
case 8:
k1 ^= uint64(data[7]) << 56
fallthrough
case 7:
k1 ^= uint64(data[6]) << 48
fallthrough
case 6:
k1 ^= uint64(data[5]) << 40
fallthrough
case 5:
k1 ^= uint64(data[4]) << 32
fallthrough
case 4:
k1 ^= uint64(data[3]) << 24
fallthrough
case 3:
k1 ^= uint64(data[2]) << 16
fallthrough
case 2:
k1 ^= uint64(data[1]) << 8
fallthrough
case 1:
k1 ^= uint64(data[0])
k1 *= c1
k1 = (k1 << 31) | (k1 >> (64 - 31))
k1 *= c2
h1 ^= k1
}
h1 ^= uint64(length)
h2 ^= uint64(length)
h1 += h2
h2 += h1
h1 = fmix(h1)
h2 = fmix(h2)
h1 += h2
h2 += h1
d.h1 = h1
d.h2 = h2
}
func (d *digest) Sum() (h1, h2 uint64) {
return d.h1, d.h2
}
func fmix(k uint64) uint64 {
k ^= k >> 33
k *= 0xff51afd7ed558ccd
k ^= k >> 33
k *= 0xc4ceb9fe1a85ec53
k ^= k >> 33
return k
}