Files
exchange_go/pkg/cryptohelper/inttostring/Inttoostr.go
2025-02-06 11:14:33 +08:00

134 lines
3.6 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 互质
}
}
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)
}
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
}