代码拉取完成,页面将自动刷新
/*
* @Author: lixu lixu@puchigames.com
* @Date: 2025-09-18 10:20:00
* @LastEditors: lixu lixu@puchigames.com
* @LastEditTime: 2025-09-18 10:20:00
* @FilePath: /go-helper/utils/id.go
* @Description: ID生成工具函数,支持UUID、雪花ID、短ID等多种ID生成方式
*/
package ixUtils
import (
"crypto/rand"
"encoding/hex"
"fmt"
"math/big"
"net"
"strconv"
"sync"
"time"
)
// ========== UUID生成 ==========
// GenerateUUID 生成标准UUID (RFC 4122 Version 4)
func GenerateUUID() string {
return GenerateUUIDv4()
}
// GenerateUUIDv4 生成UUID Version 4 (随机)
func GenerateUUIDv4() string {
// 生成16字节随机数据
bytes := make([]byte, 16)
_, err := rand.Read(bytes)
if err != nil {
// 如果随机数生成失败,使用时间戳作为fallback
return generateTimeBasedUUID()
}
// 设置版本号 (4) 和变体
bytes[6] = (bytes[6] & 0x0f) | 0x40 // Version 4
bytes[8] = (bytes[8] & 0x3f) | 0x80 // Variant 10
// 格式化为标准UUID字符串
return fmt.Sprintf("%x-%x-%x-%x-%x",
bytes[0:4], bytes[4:6], bytes[6:8], bytes[8:10], bytes[10:16])
}
// GenerateUUIDv1 生成UUID Version 1 (基于时间和MAC地址)
func GenerateUUIDv1() string {
// 获取当前时间戳 (100纳秒为单位,从1582年开始)
now := time.Now()
timestamp := uint64(now.UnixNano()/100) + 0x01B21DD213814000
// 获取MAC地址
macAddr := getMACAddress()
if macAddr == nil {
// 如果无法获取MAC地址,生成随机节点ID
macAddr = make([]byte, 6)
rand.Read(macAddr)
macAddr[0] |= 0x01 // 设置多播位
}
// 生成时钟序列
clockSeq := uint16(now.Nanosecond() & 0x3fff)
// 构建UUID
timeLow := uint32(timestamp & 0xffffffff)
timeMid := uint16((timestamp >> 32) & 0xffff)
timeHi := uint16((timestamp>>48)&0x0fff) | 0x1000 // Version 1
return fmt.Sprintf("%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
timeLow, timeMid, timeHi,
(clockSeq&0x3fff)|0x8000, // Variant 10
macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5])
}
// GenerateSimpleUUID 生成简单UUID (无连字符)
func GenerateSimpleUUID() string {
uuid := GenerateUUIDv4()
return uuid[0:8] + uuid[9:13] + uuid[14:18] + uuid[19:23] + uuid[24:36]
}
// GenerateShortUUID 生成短UUID (22字符)
func GenerateShortUUID() string {
bytes := make([]byte, 16)
rand.Read(bytes)
// 使用base62编码生成更短的字符串
return base62Encode(bytes)[:22]
}
// ========== 雪花ID (Snowflake) ==========
// SnowflakeGenerator 雪花ID生成器
type SnowflakeGenerator struct {
mutex sync.Mutex
epoch int64 // 起始时间戳 (毫秒)
workerID int64 // 工作机器ID
datacenterID int64 // 数据中心ID
sequence int64 // 序列号
lastTimestamp int64 // 上次生成ID的时间戳
}
// 雪花ID各部分的位数
const (
workerIDBits = 5 // 工作机器ID位数
datacenterIDBits = 5 // 数据中心ID位数
sequenceBits = 12 // 序列号位数
maxWorkerID = -1 ^ (-1 << workerIDBits) // 最大工作机器ID
maxDatacenterID = -1 ^ (-1 << datacenterIDBits) // 最大数据中心ID
maxSequence = -1 ^ (-1 << sequenceBits) // 最大序列号
workerIDShift = sequenceBits // 工作机器ID左移位数
datacenterIDShift = sequenceBits + workerIDBits // 数据中心ID左移位数
timestampLeftShift = sequenceBits + workerIDBits + datacenterIDBits // 时间戳左移位数
)
// 默认起始时间 (2020-01-01 00:00:00 UTC)
var defaultEpoch int64 = 1577836800000
// 全局雪花ID生成器
var globalSnowflake *SnowflakeGenerator
var snowflakeOnce sync.Once
// NewSnowflakeGenerator 创建雪花ID生成器
func NewSnowflakeGenerator(workerID, datacenterID int64) (*SnowflakeGenerator, error) {
if workerID < 0 || workerID > maxWorkerID {
return nil, fmt.Errorf("工作机器ID必须在0-%d之间", maxWorkerID)
}
if datacenterID < 0 || datacenterID > maxDatacenterID {
return nil, fmt.Errorf("数据中心ID必须在0-%d之间", maxDatacenterID)
}
return &SnowflakeGenerator{
epoch: defaultEpoch,
workerID: workerID,
datacenterID: datacenterID,
sequence: 0,
}, nil
}
// Generate 生成雪花ID
func (s *SnowflakeGenerator) Generate() int64 {
s.mutex.Lock()
defer s.mutex.Unlock()
timestamp := time.Now().UnixNano() / 1e6 // 毫秒时间戳
if timestamp < s.lastTimestamp {
// 时钟回拨,等待到下一毫秒
timestamp = s.waitNextMillis(s.lastTimestamp)
}
if timestamp == s.lastTimestamp {
// 同一毫秒内,序列号递增
s.sequence = (s.sequence + 1) & maxSequence
if s.sequence == 0 {
// 序列号溢出,等待下一毫秒
timestamp = s.waitNextMillis(s.lastTimestamp)
}
} else {
// 不同毫秒,序列号重置
s.sequence = 0
}
s.lastTimestamp = timestamp
// 生成ID
return ((timestamp - s.epoch) << timestampLeftShift) |
(s.datacenterID << datacenterIDShift) |
(s.workerID << workerIDShift) |
s.sequence
}
// waitNextMillis 等待到下一毫秒
func (s *SnowflakeGenerator) waitNextMillis(lastTimestamp int64) int64 {
timestamp := time.Now().UnixNano() / 1e6
for timestamp <= lastTimestamp {
time.Sleep(time.Millisecond)
timestamp = time.Now().UnixNano() / 1e6
}
return timestamp
}
// GenerateSnowflakeID 生成雪花ID (使用全局生成器)
func GenerateSnowflakeID() int64 {
snowflakeOnce.Do(func() {
// 自动获取工作机器ID和数据中心ID
workerID := getWorkerID()
datacenterID := getDatacenterID()
var err error
globalSnowflake, err = NewSnowflakeGenerator(workerID, datacenterID)
if err != nil {
// 如果创建失败,使用默认值
globalSnowflake, _ = NewSnowflakeGenerator(1, 1)
}
})
return globalSnowflake.Generate()
}
// ParseSnowflakeID 解析雪花ID
func ParseSnowflakeID(id int64) map[string]int64 {
timestamp := (id >> timestampLeftShift) + defaultEpoch
datacenterID := (id >> datacenterIDShift) & maxDatacenterID
workerID := (id >> workerIDShift) & maxWorkerID
sequence := id & maxSequence
return map[string]int64{
"timestamp": timestamp,
"datacenterID": datacenterID,
"workerID": workerID,
"sequence": sequence,
"time": timestamp, // 兼容字段
}
}
// ========== 短ID生成 ==========
// GenerateShortID 生成短ID (8-12字符)
func GenerateShortID() string {
return GenerateShortIDWithLength(8)
}
// GenerateShortIDWithLength 生成指定长度的短ID
func GenerateShortIDWithLength(length int) string {
if length <= 0 {
length = 8
}
// 使用时间戳 + 随机数生成
timestamp := time.Now().UnixNano()
random, _ := rand.Int(rand.Reader, big.NewInt(1000000))
combined := fmt.Sprintf("%d%d", timestamp, random.Int64())
hash := simpleHash(combined)
return base62Encode([]byte(hash))[:length]
}
// GenerateNanoID 生成NanoID风格的ID
func GenerateNanoID(size int) string {
if size <= 0 {
size = 21 // NanoID默认长度
}
// NanoID字符集
alphabet := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-"
result := make([]byte, size)
for i := 0; i < size; i++ {
randomIndex, _ := rand.Int(rand.Reader, big.NewInt(int64(len(alphabet))))
result[i] = alphabet[randomIndex.Int64()]
}
return string(result)
}
// ========== ObjectID生成 (MongoDB风格) ==========
// ObjectIDGenerator ObjectID生成器
type ObjectIDGenerator struct {
counter uint32
mutex sync.Mutex
}
var globalObjectIDGenerator = &ObjectIDGenerator{}
// GenerateObjectID 生成ObjectID (MongoDB风格)
func GenerateObjectID() string {
return globalObjectIDGenerator.Generate()
}
// Generate 生成ObjectID
func (g *ObjectIDGenerator) Generate() string {
g.mutex.Lock()
g.counter++
counter := g.counter
g.mutex.Unlock()
// ObjectID = 4字节时间戳 + 5字节随机值 + 3字节递增计数器
timestamp := uint32(time.Now().Unix())
// 生成5字节随机值
randomBytes := make([]byte, 5)
rand.Read(randomBytes)
// 3字节计数器
counterBytes := []byte{
byte(counter >> 16),
byte(counter >> 8),
byte(counter),
}
// 组合成12字节
objectID := make([]byte, 12)
// 时间戳 (4字节,大端序)
objectID[0] = byte(timestamp >> 24)
objectID[1] = byte(timestamp >> 16)
objectID[2] = byte(timestamp >> 8)
objectID[3] = byte(timestamp)
// 随机值 (5字节)
copy(objectID[4:9], randomBytes)
// 计数器 (3字节)
copy(objectID[9:12], counterBytes)
return hex.EncodeToString(objectID)
}
// ParseObjectID 解析ObjectID
func ParseObjectID(objectID string) (map[string]interface{}, error) {
if len(objectID) != 24 {
return nil, fmt.Errorf("ObjectID长度必须是24个字符")
}
bytes, err := hex.DecodeString(objectID)
if err != nil {
return nil, fmt.Errorf("ObjectID格式错误: %v", err)
}
// 解析时间戳
timestamp := uint32(bytes[0])<<24 | uint32(bytes[1])<<16 | uint32(bytes[2])<<8 | uint32(bytes[3])
createTime := time.Unix(int64(timestamp), 0)
// 解析计数器
counter := uint32(bytes[9])<<16 | uint32(bytes[10])<<8 | uint32(bytes[11])
return map[string]interface{}{
"timestamp": timestamp,
"createTime": createTime,
"counter": counter,
"randomPart": hex.EncodeToString(bytes[4:9]),
}, nil
}
// ========== 其他ID生成工具 ==========
// GenerateOrderID 生成订单ID (时间戳+随机数)
func GenerateOrderID() string {
now := time.Now()
timestamp := now.Format("20060102150405")
random := generateRandomDigits(6)
return timestamp + random
}
// GenerateTraceID 生成链路追踪ID
func GenerateTraceID() string {
return GenerateNanoID(32)
}
// GenerateSpanID 生成Span ID
func GenerateSpanID() string {
return GenerateNanoID(16)
}
// GenerateRequestID 生成请求ID
func GenerateRequestID() string {
return GenerateNanoID(16)
}
// GenerateSessionID 生成会话ID
func GenerateSessionID() string {
return GenerateNanoID(32)
}
// GenerateAPIKey 生成API密钥
func GenerateAPIKey() string {
prefix := "ak_"
id := GenerateNanoID(32)
return prefix + id
}
// GenerateSecretKey 生成密钥
func GenerateSecretKey() string {
prefix := "sk_"
id := GenerateNanoID(48)
return prefix + id
}
// ========== 工具函数 ==========
// ValidateUUID 验证UUID格式
func ValidateUUID(uuid string) bool {
if len(uuid) != 36 {
return false
}
// 检查连字符位置
if uuid[8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-' {
return false
}
// 检查每个部分是否为十六进制
parts := []string{
uuid[0:8], uuid[9:13], uuid[14:18], uuid[19:23], uuid[24:36],
}
for _, part := range parts {
for _, char := range part {
if !((char >= '0' && char <= '9') ||
(char >= 'a' && char <= 'f') ||
(char >= 'A' && char <= 'F')) {
return false
}
}
}
return true
}
// ValidateObjectID 验证ObjectID格式
func ValidateObjectID(objectID string) bool {
if len(objectID) != 24 {
return false
}
for _, char := range objectID {
if !((char >= '0' && char <= '9') ||
(char >= 'a' && char <= 'f') ||
(char >= 'A' && char <= 'F')) {
return false
}
}
return true
}
// ========== 内部辅助函数 ==========
// getMACAddress 获取MAC地址
func getMACAddress() []byte {
interfaces, err := net.Interfaces()
if err != nil {
return nil
}
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
return iface.HardwareAddr[:6]
}
}
return nil
}
// getWorkerID 获取工作机器ID
func getWorkerID() int64 {
// 基于MAC地址生成工作机器ID
macAddr := getMACAddress()
if macAddr != nil {
return int64(macAddr[len(macAddr)-1]) & maxWorkerID
}
// 如果无法获取MAC地址,使用随机数
random, _ := rand.Int(rand.Reader, big.NewInt(maxWorkerID+1))
return random.Int64()
}
// getDatacenterID 获取数据中心ID
func getDatacenterID() int64 {
// 基于主机名或其他标识生成数据中心ID
// 这里使用简单的随机数,实际使用时可以根据部署环境配置
random, _ := rand.Int(rand.Reader, big.NewInt(maxDatacenterID+1))
return random.Int64()
}
// base62Encode Base62编码
func base62Encode(data []byte) string {
alphabet := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
// 将字节数组转换为大整数
num := big.NewInt(0)
num.SetBytes(data)
if num.Cmp(big.NewInt(0)) == 0 {
return string(alphabet[0])
}
result := ""
base := big.NewInt(62)
zero := big.NewInt(0)
for num.Cmp(zero) > 0 {
mod := big.NewInt(0)
num.DivMod(num, base, mod)
result = string(alphabet[mod.Int64()]) + result
}
return result
}
// simpleHash 简单哈希函数
func simpleHash(s string) string {
hash := uint32(0)
for _, char := range s {
hash = hash*31 + uint32(char)
}
return strconv.FormatUint(uint64(hash), 16)
}
// generateTimeBasedUUID 基于时间生成UUID (fallback)
func generateTimeBasedUUID() string {
now := time.Now()
timestamp := now.UnixNano()
// 使用时间戳生成UUID
return fmt.Sprintf("%08x-%04x-4%03x-%04x-%012x",
uint32(timestamp&0xffffffff),
uint16((timestamp>>32)&0xffff),
uint16((timestamp>>48)&0x0fff),
uint16(now.Nanosecond()&0x3fff)|0x8000,
uint64(now.UnixNano())&0xffffffffffff)
}
// generateRandomDigits 生成指定长度的随机数字字符串
func generateRandomDigits(length int) string {
digits := "0123456789"
result := make([]byte, length)
for i := 0; i < length; i++ {
randomIndex, _ := rand.Int(rand.Reader, big.NewInt(int64(len(digits))))
result[i] = digits[randomIndex.Int64()]
}
return string(result)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。