package utility import ( "strconv" "strings" "github.com/rs/xid" "go.uber.org/zap" cryptoRand "crypto/rand" "fmt" "math" "math/big" "math/rand" "time" log "github.com/go-admin-team/go-admin-core/logger" "github.com/sony/sonyflake" ) const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // GetXid Package xid is a globally unique id generator library // 包xid是一个全局唯一的id生成器库 func GetXid() string { return xid.New().String() } // GetRandIntStr 生成len位的随机数字 func GetRandIntStr(len int, prefix string) string { rand.Seed(time.Now().UnixNano()) num := rand.Int31n(int32(math.Pow(10, float64(len)))) x := fmt.Sprintf("%s%0*d", prefix, len, num) return x } // GenerateRandString 生成指定位数的字符串 // 虽然繁琐 但理解之后就觉得很精妙 func GenerateRandString(length int) string { var chars = []byte(`ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`) // 长度:(1,256) rand.Seed(time.Now().UnixNano()) clen := len(chars) maxRb := 255 - (256 % clen) // [-1,255] 255 - (256%36) = 251 避免模偏倚 为了每个字符被取到的几率相等 b := make([]byte, length) r := make([]byte, length+(length/4)) // storage for random bytes. 存储随机字节 for i := 0; ; { // 将随机的byte值填充到byte数组中 以供使用 if _, err := rand.Read(r); err != nil { log.Error(`GenerateRandString`, zap.Error(err)) return `` } for _, rb := range r { c := int(rb) if c > maxRb { // Skip this number to avoid modulo bias.跳过这个数字以避免模偏倚 continue } b[i] = chars[c%clen] i++ if i == length { // 直到取到合适的长度 return string(b) } } } } // GenerateBase62Key 生成指定长度的随机 Base62(数字 + 大小写字母)字符串 func GenerateBase62Key(length int) (string, error) { var b strings.Builder b.Grow(length) for i := 0; i < length; i++ { n, err := cryptoRand.Int(cryptoRand.Reader, big.NewInt(int64(len(base62Chars)))) if err != nil { return "", err } b.WriteByte(base62Chars[n.Int64()]) } return b.String(), nil } var sf *sonyflake.Sonyflake func InitSnowflake() { sf = sonyflake.NewSonyflake(sonyflake.Settings{}) if sf == nil { log.Fatalf("Failed to initialize sonyflake") } } func GenerateTraceID() string { id, err := sf.NextID() if err != nil { log.Fatalf("Failed to generate ID: %v", err) } return strconv.FormatUint(id, 10) }