1
This commit is contained in:
133
pkg/cryptohelper/inttostring/Inttoostr.go
Normal file
133
pkg/cryptohelper/inttostring/Inttoostr.go
Normal file
@ -0,0 +1,133 @@
|
||||
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
|
||||
}
|
||||
33
pkg/cryptohelper/inttostring/Inttoostr_test.go
Normal file
33
pkg/cryptohelper/inttostring/Inttoostr_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
package inttostring
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
||||
func Test_a(t *testing.T) {
|
||||
a:=1156
|
||||
// b:=byte(a)
|
||||
fmt.Println(a%10)
|
||||
}
|
||||
// 加密解密
|
||||
func Test_EnDecode(t *testing.T) {
|
||||
uid := 6515461646
|
||||
Invi := NewInvite()
|
||||
encode := Invi.Encode(uid)
|
||||
DeCode := Invi.DeCode(encode)
|
||||
fmt.Println(`原始为`, uid)
|
||||
fmt.Println(`加密后`, encode)
|
||||
fmt.Println(`解密后`, DeCode)
|
||||
}
|
||||
|
||||
func Test_Invite(t *testing.T) {
|
||||
for uid := 0; uid < 10000000; uid++ {
|
||||
encode := Invite.Encode(uid)
|
||||
DeCode := Invite.DeCode(encode)
|
||||
if DeCode != uid {
|
||||
t.Fatal(`加密解密错误`, DeCode, uid)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user