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)
							 | 
						|||
| 
								 | 
							
								}
							 |