Files
exchange_go/pkg/cryptohelper/inttostring/Inttoostr.go
2025-02-27 15:05:34 +08:00

172 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}