hi-server/pkg/tool/device.go
shanshanzhong de6fbcb518
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m22s
device_no
2026-03-18 10:28:55 -07:00

64 lines
2.1 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 tool
import (
"fmt"
"strings"
)
// 乘法逆元参数mod 2^32
// multiplier 必须是奇数,与 2^32 互质
// inverse 满足: multiplier * inverse ≡ 1 (mod 2^32)
const (
deviceMultiplier uint32 = 0x45D9F3B7 // 奇数乘数
deviceInverse uint32 = 0x9B845A07 // 乘法逆元 (multiplier * inverse = 1 mod 2^32)
deviceXorKey1 uint32 = 0x5A3C7E9B // 第一轮 XOR
deviceXorKey2 uint32 = 0xE7B2A4C3 // 第二轮 XOR
)
// bitShuffle 交错重排 32 位的比特位,打散高低位的关联
func bitShuffle(v uint32) uint32 {
var result uint32
// 把偶数位放到高16位奇数位放到低16位
for i := 0; i < 16; i++ {
result |= ((v >> (2 * i)) & 1) << (16 + i) // 偶数位 → 高半
result |= ((v >> (2*i + 1)) & 1) << i // 奇数位 → 低半
}
return result
}
// bitUnshuffle 是 bitShuffle 的逆操作
func bitUnshuffle(v uint32) uint32 {
var result uint32
for i := 0; i < 16; i++ {
result |= ((v >> (16 + i)) & 1) << (2 * i) // 高半 → 偶数位
result |= ((v >> i) & 1) << (2*i + 1) // 低半 → 奇数位
}
return result
}
// DeviceIdToHash encodes a device id to an 8-char uppercase hex string.
// Uses multiply-xor-shuffle to fully scatter sequential IDs.
// e.g. 1 → "83AEF73C", 2 → "D603916F" (no visible pattern)
func DeviceIdToHash(id int64) string {
n := uint32(id)
n ^= deviceXorKey1 // step 1: XOR
n *= deviceMultiplier // step 2: 乘法扩散(模 2^32
n = bitShuffle(n) // step 3: 比特位交错
n ^= deviceXorKey2 // step 4: 再次 XOR
return strings.ToUpper(fmt.Sprintf("%08x", n))
}
// HashToDeviceId decodes an 8-char hex hash back to a device id.
func HashToDeviceId(hash string) (int64, error) {
var n uint32
_, err := fmt.Sscanf(strings.ToLower(hash), "%08x", &n)
if err != nil {
return 0, err
}
n ^= deviceXorKey2 // reverse step 4
n = bitUnshuffle(n) // reverse step 3
n *= deviceInverse // reverse step 2: 乘法逆元
n ^= deviceXorKey1 // reverse step 1
return int64(n), nil
}