101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
|
|
package utility
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"strconv"
|
|||
|
|
"strings"
|
|||
|
|
|
|||
|
|
"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/rs/xid"
|
|||
|
|
"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)
|
|||
|
|
}
|