1
Some checks failed
Build / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
build / Build (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitee (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitlab (push) Has been cancelled
Issue Close Require / issue-close-require (push) Has been cancelled
Issue Check Inactive / issue-check-inactive (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
build / Build (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitee (push) Has been cancelled
GitHub Actions Mirror / mirror_to_gitlab (push) Has been cancelled
Issue Close Require / issue-close-require (push) Has been cancelled
Issue Check Inactive / issue-check-inactive (push) Has been cancelled
This commit is contained in:
81
utils/utility/id_helper.go
Normal file
81
utils/utility/id_helper.go
Normal file
@ -0,0 +1,81 @@
|
||||
package utility
|
||||
|
||||
import (
|
||||
"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"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
29
utils/utility/slice.go
Normal file
29
utils/utility/slice.go
Normal file
@ -0,0 +1,29 @@
|
||||
package utility
|
||||
|
||||
// SplitSlice 将 []string 切片根据最大数量分割成二维数组
|
||||
func SplitSlice[T any](slice []T, maxSize int) [][]T {
|
||||
var result [][]T
|
||||
|
||||
// 遍历切片,每次取 maxSize 个元素
|
||||
for i := 0; i < len(slice); i += maxSize {
|
||||
end := i + maxSize
|
||||
// 如果 end 超出切片长度,则取到切片末尾
|
||||
if end > len(slice) {
|
||||
end = len(slice)
|
||||
}
|
||||
// 将当前段添加到结果中
|
||||
result = append(result, slice[i:end])
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ContainsInt []int 包含元素?
|
||||
func ContainsInt(arr []int, v int) bool {
|
||||
for _, a := range arr {
|
||||
if a == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
63
utils/utility/string_helper.go
Normal file
63
utils/utility/string_helper.go
Normal file
@ -0,0 +1,63 @@
|
||||
package utility
|
||||
|
||||
import "strings"
|
||||
|
||||
// DesensitizeGeneric 通用脱敏函数:
|
||||
// startReserveCount: 从字符串开头保留的字符数
|
||||
// endReserveCount: 从字符串末尾保留的字符数
|
||||
// asteriskChar: 用于替换的字符 (例如 '*')
|
||||
// 例如:DesensitizeGeneric("这是一个秘密信息", 2, 2, '*') -> 这**信息
|
||||
func DesensitizeGeneric(text string, startReserveCount int, endReserveCount int, asteriskChar rune) string {
|
||||
if text == "" {
|
||||
return ""
|
||||
}
|
||||
runes := []rune(text)
|
||||
length := len(runes)
|
||||
|
||||
// 计算实际需要保留的总字符数
|
||||
totalReservedLength := startReserveCount + endReserveCount
|
||||
|
||||
// 如果需要保留的字符数大于等于总长度,则不脱敏
|
||||
if totalReservedLength >= length {
|
||||
return text
|
||||
}
|
||||
|
||||
// 确保保留位数不为负数
|
||||
if startReserveCount < 0 {
|
||||
startReserveCount = 0
|
||||
}
|
||||
if endReserveCount < 0 {
|
||||
endReserveCount = 0
|
||||
}
|
||||
|
||||
// 如果保留总长度为0,且字符串不为空,则全部脱敏
|
||||
if totalReservedLength == 0 && length > 0 {
|
||||
return strings.Repeat(string(asteriskChar), length)
|
||||
}
|
||||
|
||||
// 确保保留的长度不超过总长度
|
||||
if startReserveCount > length {
|
||||
startReserveCount = length
|
||||
}
|
||||
if endReserveCount > length-startReserveCount {
|
||||
endReserveCount = length - startReserveCount
|
||||
}
|
||||
|
||||
// 构造脱敏字符串
|
||||
var sb strings.Builder
|
||||
// 写入前缀
|
||||
if startReserveCount > 0 {
|
||||
sb.WriteString(string(runes[0:startReserveCount]))
|
||||
}
|
||||
// 写入星号
|
||||
asteriskCount := length - startReserveCount - endReserveCount
|
||||
if asteriskCount > 0 {
|
||||
sb.WriteString(strings.Repeat(string(asteriskChar), asteriskCount))
|
||||
}
|
||||
// 写入后缀
|
||||
if endReserveCount > 0 && length-endReserveCount >= startReserveCount { // 确保后缀不与前缀重叠
|
||||
sb.WriteString(string(runes[length-endReserveCount:]))
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
Reference in New Issue
Block a user