goProject/trunk/goutil/dfaExUtil/hash32/hash32.go
皮蛋13361098506 1b77f62820 初始化项目
2025-01-06 16:01:02 +08:00

99 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package hash32
/*
* ***注意***
*
* Sum 使用的是[]byte参数string中文是utf-8编码
* SumByRune 使用的是[]rune参数中文使用的是unicode编码
*
* 两种参数中文编码不同同一个string调用两个接口得到的hash是不同的 这是要特别注意的
*
* 对string进行for range操作会自动被[]rune化一定要注意
*
*/
const shiftBit = 11 // 每个字节移位数(测试经验值11)
const reverseBit = 32 - shiftBit
// 快速Hash计算(*** 注意只取了rune低16位进行hash计算计算结果与SumByRune不一致 ***)
func FastSumByRune2(in rune, hs uint32) (out uint32) {
out = ((hs << shiftBit) | (hs >> reverseBit)) + uint32(byte(in>>8))
out = ((out << shiftBit) | (out >> reverseBit)) + uint32(byte(in))
return
}
// 快速Hash计算(*** 此计算结果与SumByRune一致 ***)
func FastSumByRune4(in rune, hs uint32) (out uint32) {
out = ((hs << shiftBit) | (hs >> reverseBit)) + uint32(byte(in>>24))
out = ((out << shiftBit) | (out >> reverseBit)) + uint32(byte(in>>16))
out = ((out << shiftBit) | (out >> reverseBit)) + uint32(byte(in>>8))
out = ((out << shiftBit) | (out >> reverseBit)) + uint32(byte(in))
return
}
// 原Hash值参数重
func hsArg(hsOpt ...uint32) (out uint32) {
out = uint32(0)
if len(hsOpt) > 0 {
out = hsOpt[0]
}
return
}
// Hash计算
// in - 待hash串
// hsOpt - 原hash值(在此基础上继续hash)
func Sum(in []byte, hsOpt ...uint32) (out uint32) {
out = hsArg(hsOpt...)
for _, v := range in {
out = ((out << shiftBit) | (out >> reverseBit)) + uint32(v)
}
return
}
// Hash计算
func SumByRune(in rune, hsOpt ...uint32) (out uint32) {
// rune转[]byte
inVal := make([]byte, 4)
inVal[0] = byte(in >> 24)
inVal[1] = byte(in >> 16)
inVal[2] = byte(in >> 8)
inVal[3] = byte(in)
// *** 经实际测试:不加以下代码运行效率更高 ***
// 去除前面多余的\x00
// for {
// if len(inVal) <= 1 {
// // 以免全0异常至少要保留1位
// break
// }
// if inVal[0] == 0 {
// inVal = inVal[1:]
// } else {
// break
// }
// }
// 规避hash冲突"N-"与"中"unicode编码均为#4E2D即会产生hash冲突
// 若长度>1(即非常规ASCII)所有字节最高位置1
// if len(inVal) > 1 {
// for i := 0; i < len(inVal); i++ {
// inVal[i] |= 0x80
// }
// }
out = Sum(inVal, hsOpt...)
return
}
// Hash计算
func SumByRunes(in []rune, hsOpt ...uint32) (out uint32) {
out = hsArg(hsOpt...)
for _, v := range in {
out = SumByRune(v, out)
}
return
}