Fetch the repository succeeded.
package metrohash
/*
算法名称: MetroHash
算法类型: 高速非加密哈希
主要特点: 比 CityHash 更快,适合大数据块
应用场景: 数据去重、大文件校验、高速缓存
*/
import (
"encoding/binary"
"encoding/hex"
"gitee.com/ochumilov/rem-algo/integrity/common"
)
// MetroHash 常量
const (
k0 uint64 = 0xD6D018F5
k1 uint64 = 0xA2AA033B
k2 uint64 = 0x62992FC1
k3 uint64 = 0x30BC5B29
)
// MetroHasher MetroHash64 哈希器
type MetroHasher struct {
seed uint64
}
// NewMetroHasher 创建 MetroHash64 哈希器
func NewMetroHasher() *MetroHasher {
return &MetroHasher{seed: 0}
}
// NewMetroHasherWithSeed 创建带种子的 MetroHash64 哈希器
func NewMetroHasherWithSeed(seed uint64) *MetroHasher {
return &MetroHasher{seed: seed}
}
// Sum64 计算 MetroHash64 哈希值
func (h *MetroHasher) Sum64(data []byte) uint64 {
return MetroHash64(data, h.seed)
}
// Sum 返回哈希值的字节切片
func (h *MetroHasher) Sum(data []byte) []byte {
hash := MetroHash64(data, h.seed)
result := make([]byte, 8)
binary.BigEndian.PutUint64(result, hash)
return result
}
// SumHex 返回哈希值的十六进制字符串
func (h *MetroHasher) SumHex(data []byte) string {
return hex.EncodeToString(h.Sum(data))
}
// Type 返回校验类型
func (h *MetroHasher) Type() common.IntegrityType {
return common.METROHASH64
}
// -------------------- 核心算法 --------------------
// MetroHash64 计算 MetroHash64
func MetroHash64(data []byte, seed uint64) uint64 {
n := len(data)
hash := (seed + k2) * k0
if n >= 32 {
v0 := hash
v1 := hash
v2 := hash
v3 := hash
for len(data) >= 32 {
v0 += fetch64(data) * k0
v0 = rotateRight64(v0, 29) + v2
v1 += fetch64(data[8:]) * k1
v1 = rotateRight64(v1, 29) + v3
v2 += fetch64(data[16:]) * k2
v2 = rotateRight64(v2, 29) + v0
v3 += fetch64(data[24:]) * k3
v3 = rotateRight64(v3, 29) + v1
data = data[32:]
}
v2 ^= rotateRight64(((v0+v3)*k0)+v1, 37) * k1
v3 ^= rotateRight64(((v1+v2)*k1)+v0, 37) * k0
v0 ^= rotateRight64(((v0+v2)*k0)+v3, 37) * k1
v1 ^= rotateRight64(((v1+v3)*k1)+v2, 37) * k0
hash += v0 ^ v1
}
if len(data) >= 16 {
v0 := hash + (fetch64(data) * k2)
v0 = rotateRight64(v0, 29) * k3
v1 := hash + (fetch64(data[8:]) * k2)
v1 = rotateRight64(v1, 29) * k3
v0 ^= rotateRight64(v0*k0, 21) + v1
v1 ^= rotateRight64(v1*k3, 21) + v0
hash += v1
data = data[16:]
}
if len(data) >= 8 {
hash += fetch64(data) * k3
hash ^= rotateRight64(hash, 55) * k1
data = data[8:]
}
if len(data) >= 4 {
hash += uint64(fetch32(data)) * k3
hash ^= rotateRight64(hash, 26) * k1
data = data[4:]
}
if len(data) >= 2 {
hash += uint64(fetch16(data)) * k3
hash ^= rotateRight64(hash, 48) * k1
data = data[2:]
}
if len(data) >= 1 {
hash += uint64(data[0]) * k3
hash ^= rotateRight64(hash, 37) * k1
}
hash ^= rotateRight64(hash, 28)
hash *= k0
hash ^= rotateRight64(hash, 29)
return hash
}
// MetroHash64String 计算字符串的 MetroHash64
func MetroHash64String(s string, seed uint64) uint64 {
return MetroHash64([]byte(s), seed)
}
// SumHex 计算 MetroHash64 并返回十六进制字符串
func SumHex(data []byte) string {
hash := MetroHash64(data, 0)
result := make([]byte, 8)
binary.BigEndian.PutUint64(result, hash)
return hex.EncodeToString(result)
}
// -------------------- 辅助函数 --------------------
func fetch64(p []byte) uint64 {
return binary.LittleEndian.Uint64(p)
}
func fetch32(p []byte) uint32 {
return binary.LittleEndian.Uint32(p)
}
func fetch16(p []byte) uint16 {
return binary.LittleEndian.Uint16(p)
}
func rotateRight64(v uint64, k uint) uint64 {
return (v >> k) | (v << (64 - k))
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。