1 Star 1 Fork 3

menuiis/gkit

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
hash128.go 11.14 KB
一键复制 编辑 原始数据 按行查看 历史
menuis 提交于 2024-04-22 10:18 +08:00 . init
// Package xxhash3 implements https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h
package xxhash3
import (
"gitee.com/menciis/gkit/internal/hack"
"gitee.com/menciis/gkit/internal/runtimex"
"math/bits"
"unsafe"
)
// Hash128 returns the hash value of the byte slice in 128bits.
func Hash128(data []byte) [2]uint64 {
funcPointer := hashSmall
if len(data) > 16 {
funcPointer = hashLarge
}
return hashfunc128[funcPointer](*(*unsafe.Pointer)(unsafe.Pointer(&data)), len(data))
}
// Hash128String returns the hash value of the string in 128bits.
func Hash128String(s string) [2]uint64 {
return Hash128(hack.StringToBytes(s))
}
func xxh3HashSmall128(xinput unsafe.Pointer, l int) [2]uint64 {
length := uint64(l)
var h128Low64 uint64
var h128High64 uint64
if length > 8 {
bitflipl := xsecret_032 ^ xsecret_040
bitfliph := xsecret_048 ^ xsecret_056
inputLow := runtimex.ReadUnaligned64(xinput)
inputHigh := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + uintptr(length) - 8))
m128High64, m128Low64 := bits.Mul64(inputLow^inputHigh^bitflipl, prime64_1)
m128Low64 += uint64(length-1) << 54
inputHigh ^= bitfliph
m128High64 += inputHigh + uint64(uint32(inputHigh))*(prime32_2-1)
m128Low64 ^= bits.ReverseBytes64(m128High64)
h128High64, h128Low64 = bits.Mul64(m128Low64, prime64_2)
h128High64 += m128High64 * prime64_2
h128Low64 = xxh3Avalanche(h128Low64)
h128High64 = xxh3Avalanche(h128High64)
return [2]uint64{h128High64, h128Low64}
} else if length >= 4 {
inputLow := runtimex.ReadUnaligned32(xinput)
inputHigh := runtimex.ReadUnaligned32(unsafe.Pointer(uintptr(xinput) + uintptr(length) - 4))
input64 := inputLow + (uint64(inputHigh) << 32)
bitflip := xsecret_016 ^ xsecret_024
keyed := input64 ^ bitflip
h128High64, h128Low64 = bits.Mul64(keyed, prime64_1+(length)<<2)
h128High64 += h128Low64 << 1
h128Low64 ^= h128High64 >> 3
h128Low64 ^= h128Low64 >> 35
h128Low64 *= 0x9fb21c651e98df25
h128Low64 ^= h128Low64 >> 28
h128High64 = xxh3Avalanche(h128High64)
return [2]uint64{h128High64, h128Low64}
} else if length == 3 {
c12 := runtimex.ReadUnaligned16(xinput)
c3 := uint64(*(*uint8)(unsafe.Pointer(uintptr(xinput) + 2)))
h128Low64 = c12<<16 + c3 + 3<<8
} else if length == 2 {
c12 := runtimex.ReadUnaligned16(xinput)
h128Low64 = c12*(1<<24+1)>>8 + 2<<8
} else if length == 1 {
c1 := uint64(*(*uint8)(xinput))
h128Low64 = c1*(1<<24+1<<16+1) + 1<<8
} else if length == 0 {
return [2]uint64{0x99aa06d3014798d8, 0x6001c324468d497f}
}
h128High64 = uint64(bits.RotateLeft32(bits.ReverseBytes32(uint32(h128Low64)), 13))
bitflipl := uint64(xsecret32_000 ^ xsecret32_004)
bitfliph := uint64(xsecret32_008 ^ xsecret32_012)
h128Low64 = h128Low64 ^ bitflipl
h128High64 = h128High64 ^ bitfliph
h128Low64 = xxh64Avalanche(h128Low64)
h128High64 = xxh64Avalanche(h128High64)
return [2]uint64{h128High64, h128Low64}
}
func xxh3HashLarge128(xinput unsafe.Pointer, l int) (acc [2]uint64) {
length := uintptr(l)
if length <= 128 {
accHigh := uint64(0)
accLow := uint64(length * prime64_1)
if length > 32 {
if length > 64 {
if length > 96 {
accLow += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+48))^xsecret_096, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+56))^xsecret_104)
accLow ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-64))) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-56)))
accHigh += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-64)))^xsecret_112, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-56)))^xsecret_120)
accHigh ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+48)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+56))
}
accLow += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32))^xsecret_064, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+40))^xsecret_072)
accLow ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-48))) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-40)))
accHigh += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-48)))^xsecret_080, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-40)))^xsecret_088)
accHigh ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+40))
}
accLow += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+16))^xsecret_032, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+3*8))^xsecret_040)
accLow ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-32))) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-3*8)))
accHigh += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-32)))^xsecret_048, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-3*8)))^xsecret_056)
accHigh ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+3*8))
}
accLow += mix(runtimex.ReadUnaligned64(xinput)^xsecret_000, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+8))^xsecret_008)
accLow ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-16))) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-8)))
accHigh += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-16)))^xsecret_016, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(length-8)))^xsecret_024)
accHigh ^= runtimex.ReadUnaligned64(xinput) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+8))
h128Low := accHigh + accLow
h128High := (accLow * prime64_1) + (accHigh * prime64_4) + uint64(length*prime64_2)
h128Low = xxh3Avalanche(h128Low)
h128High = -xxh3Avalanche(h128High)
return [2]uint64{h128High, h128Low}
} else if length <= 240 {
accLow64 := uint64(length * prime64_1)
accHigh64 := uint64(0)
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*0))^xsecret_000, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+8))^xsecret_008)
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*0+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+24))
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*0+16))^xsecret_016, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+24))^xsecret_024)
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*0)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+8))
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1))^xsecret_032, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1+8))^xsecret_040)
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1+24))
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1+16))^xsecret_048, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1+24))^xsecret_056)
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*1)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+uintptr(32*1)+8))
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2))^xsecret_064, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+8))^xsecret_072)
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+24))
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+16))^xsecret_080, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+24))^xsecret_088)
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*2+8))
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3))^xsecret_096, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+8))^xsecret_104)
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+24))
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+16))^xsecret_112, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+24))^xsecret_120)
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+32*3+8))
accLow64 = xxh3Avalanche(accLow64)
accHigh64 = xxh3Avalanche(accHigh64)
nbRounds := uintptr(length >> 5 << 5)
for i := uintptr(4 * 32); i < nbRounds; i += 32 {
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+16))^runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xsecret)+i-109)), runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+24))^runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xsecret)+i-101)))
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+8))
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i))^runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xsecret)+i-125)), runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+8))^runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xsecret)+i-117)))
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+i+24))
}
// last 32 bytes
accLow64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-16))^xsecret_103, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-8))^xsecret_111)
accLow64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-32)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-24))
accHigh64 += mix(runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-32))^xsecret_119, runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-24))^xsecret_127)
accHigh64 ^= runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-16)) + runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput)+length-8))
accHigh64, accLow64 = (accLow64*prime64_1)+(accHigh64*prime64_4)+uint64(length*prime64_2), accHigh64+accLow64
accLow64 = xxh3Avalanche(accLow64)
accHigh64 = -xxh3Avalanche(accHigh64)
return [2]uint64{accHigh64, accLow64}
}
var xacc = [8]uint64{
prime32_3, prime64_1, prime64_2, prime64_3,
prime64_4, prime32_2, prime64_5, prime32_1}
acc[1] = uint64(length * prime64_1)
acc[0] = uint64(^(length * prime64_2))
accum(&xacc, xinput, xsecret, length)
// merge xacc
acc[1] += mix(xacc[0]^xsecret_011, xacc[1]^xsecret_019)
acc[1] += mix(xacc[2]^xsecret_027, xacc[3]^xsecret_035)
acc[1] += mix(xacc[4]^xsecret_043, xacc[5]^xsecret_051)
acc[1] += mix(xacc[6]^xsecret_059, xacc[7]^xsecret_067)
acc[1] = xxh3Avalanche(acc[1])
acc[0] += mix(xacc[0]^xsecret_117, xacc[1]^xsecret_125)
acc[0] += mix(xacc[2]^xsecret_133, xacc[3]^xsecret_141)
acc[0] += mix(xacc[4]^xsecret_149, xacc[5]^xsecret_157)
acc[0] += mix(xacc[6]^xsecret_165, xacc[7]^xsecret_173)
acc[0] = xxh3Avalanche(acc[0])
return acc
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/menciis/gkit.git
git@gitee.com:menciis/gkit.git
menciis
gkit
gkit
d3f65ed26d21

搜索帮助