172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package inttostring
 | 
						||
 | 
						||
import (
 | 
						||
	"math"
 | 
						||
	"math/rand"
 | 
						||
	"strings"
 | 
						||
	"time"
 | 
						||
)
 | 
						||
 | 
						||
// IntToStr 用于将数字映射为字符串 例如 用户id-->邀请码
 | 
						||
type IntToStr struct {
 | 
						||
	SALT            int  // 随意取一个数值
 | 
						||
	Len             int  // 邀请码长度
 | 
						||
	PRIME2          byte // 与邀请码长度 8 互质
 | 
						||
	AlphanumericSet []rune
 | 
						||
	PRIME1          int // 与字符集长度 36 互质
 | 
						||
}
 | 
						||
 | 
						||
var (
 | 
						||
	Invite = NewInvite() // 邀请码
 | 
						||
)
 | 
						||
 | 
						||
// NewInvite 邀请码
 | 
						||
func NewInvite() *IntToStr {
 | 
						||
	return &IntToStr{
 | 
						||
		SALT:   15151239, // 随意取一个数值
 | 
						||
		Len:    8,        // 邀请码长度
 | 
						||
		PRIME2: 3,        // 与邀请码长度 Len 互质
 | 
						||
		AlphanumericSet: []rune{
 | 
						||
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 | 
						||
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
 | 
						||
			'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
 | 
						||
		}, // 邀请码长度
 | 
						||
		PRIME1: 5, // 与字符集长度 36 互质
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// NewInvite 数字邀请码
 | 
						||
func NewNumberInvite() *IntToStr {
 | 
						||
	return &IntToStr{
 | 
						||
		SALT:   15151239, // 随意取一个数值
 | 
						||
		Len:    9,        // 邀请码长度
 | 
						||
		PRIME2: 3,        // 与邀请码长度 Len 互质
 | 
						||
		AlphanumericSet: []rune{
 | 
						||
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 | 
						||
		}, // 邀请码长度
 | 
						||
		PRIME1: 3, // 与字符集长度 10 互质
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func (in IntToStr) DeCode(codeStr string) int {
 | 
						||
	code := make([]rune, 0, in.Len)
 | 
						||
	var key rune = 0
 | 
						||
	// 还原k
 | 
						||
	for i := 0; i < in.Len; i++ {
 | 
						||
		for k, v := range in.AlphanumericSet {
 | 
						||
			if v == rune(codeStr[i]) {
 | 
						||
				key = rune(k)
 | 
						||
				break
 | 
						||
			}
 | 
						||
		}
 | 
						||
		code = append(code, key)
 | 
						||
	}
 | 
						||
	code2 := make([]rune, 0, in.Len)
 | 
						||
	// 还原顺序
 | 
						||
	for i := 0; i < in.Len; i++ {
 | 
						||
		idx := i * int(in.PRIME2) % in.Len
 | 
						||
		code2 = append(code2, code[idx])
 | 
						||
	}
 | 
						||
 | 
						||
	// 还原数字
 | 
						||
	var x int
 | 
						||
	for i := 0; i < in.Len; i++ {
 | 
						||
		code2[i] = (code2[i] - rune(i)*code2[0]) % rune(len(in.AlphanumericSet))
 | 
						||
		code2[i] = (code2[i] + rune(len(in.AlphanumericSet))) % rune(len(in.AlphanumericSet))
 | 
						||
		place := math.Pow(float64(len(in.AlphanumericSet)), float64(i)) // 次方运算
 | 
						||
		x += int(code2[i]) * int(place)
 | 
						||
	}
 | 
						||
	//  去盐  + 缩小
 | 
						||
	x = (x - in.SALT) / in.PRIME1
 | 
						||
 | 
						||
	return x
 | 
						||
}
 | 
						||
 | 
						||
func (in IntToStr) Encode(uid int) string {
 | 
						||
	// 放大 + 加盐
 | 
						||
	uid = uid*in.PRIME1 + in.SALT
 | 
						||
	slIdx := make([]byte, in.Len)
 | 
						||
 | 
						||
	// 扩散
 | 
						||
	for i := 0; i < in.Len; i++ {
 | 
						||
		slIdx[i] = byte(uid % len(in.AlphanumericSet))                           // 转换进制 获取36进制的每一位值
 | 
						||
		slIdx[i] = (slIdx[i] + byte(i)*slIdx[0]) % byte(len(in.AlphanumericSet)) // 其他位与个位加和再取余(让个位的变化影响到所有位)
 | 
						||
		uid = uid / len(in.AlphanumericSet)                                      // 相当于右移一位(62进制)
 | 
						||
	}
 | 
						||
 | 
						||
	var code []rune
 | 
						||
	// 混淆
 | 
						||
	for i := 0; i < in.Len; i++ {
 | 
						||
		idx := (byte(i) * in.PRIME2) % byte(in.Len)
 | 
						||
		code = append(code, in.AlphanumericSet[slIdx[idx]])
 | 
						||
	}
 | 
						||
	return string(code)
 | 
						||
}
 | 
						||
 | 
						||
func (i IntToStr) GenerateRandomCode(num int) string {
 | 
						||
	// 用当前时间 + 随机数生成编码基础值
 | 
						||
	rand.Seed(time.Now().UnixNano()) // Ensure randomness
 | 
						||
	num = num + rand.Intn(10000)     // 通过加入随机数,避免重复
 | 
						||
 | 
						||
	// 对输入进行基础的模运算,避免直接按时间戳生成
 | 
						||
	var result []rune
 | 
						||
	for num > 0 {
 | 
						||
		result = append(result, i.AlphanumericSet[num%len(i.AlphanumericSet)])
 | 
						||
		num = num / len(i.AlphanumericSet)
 | 
						||
	}
 | 
						||
 | 
						||
	// 返回编码后的字符串,并保证字符串长度固定
 | 
						||
	for len(result) < i.Len {
 | 
						||
		result = append(result, i.AlphanumericSet[rand.Intn(len(i.AlphanumericSet))])
 | 
						||
	}
 | 
						||
 | 
						||
	// 将结果逆序,保证更好的随机性
 | 
						||
	for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
 | 
						||
		result[i], result[j] = result[j], result[i]
 | 
						||
	}
 | 
						||
 | 
						||
	return string(result)
 | 
						||
}
 | 
						||
 | 
						||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 | 
						||
const smsLetters = "0123456789"
 | 
						||
 | 
						||
// GenerateRandomString 生成指定长度的随机字符串
 | 
						||
func GenerateRandomString(n int) string {
 | 
						||
	rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
 | 
						||
	result := make([]byte, n)
 | 
						||
	for i := range result {
 | 
						||
		result[i] = letters[rand.Intn(len(letters))]
 | 
						||
	}
 | 
						||
	return string(result)
 | 
						||
}
 | 
						||
 | 
						||
// GenerateRandomSmsString 生成指定长度的随机字符串
 | 
						||
func GenerateRandomSmsString(n int) string {
 | 
						||
	rand.Seed(time.Now().UnixNano()) // 初始化随机数种子
 | 
						||
	result := make([]byte, n)
 | 
						||
	for i := range result {
 | 
						||
		result[i] = smsLetters[rand.Intn(len(smsLetters))]
 | 
						||
	}
 | 
						||
	return string(result)
 | 
						||
}
 | 
						||
 | 
						||
func EncryptString(s string, prefixLen, suffixLen int) string {
 | 
						||
	length := len(s)
 | 
						||
 | 
						||
	// 如果字符串长度不足,直接返回原字符串
 | 
						||
	if length <= prefixLen+suffixLen {
 | 
						||
		return s
 | 
						||
	}
 | 
						||
 | 
						||
	// 保留前 prefixLen 位和后 suffixLen 位
 | 
						||
	prefix := s[:prefixLen]
 | 
						||
	suffix := s[length-suffixLen:]
 | 
						||
 | 
						||
	// 中间部分用 * 替换
 | 
						||
	middle := strings.Repeat("*", 6)
 | 
						||
 | 
						||
	// 拼接结果
 | 
						||
	return prefix + middle + suffix
 | 
						||
}
 |