library-go/utils/invited_code/convert.go

81 lines
1.6 KiB
Go

package invited_code
import (
"fmt"
"math"
"strings"
)
type Converter struct {
Base int
Length int
ConvertTable []string
}
func (c *Converter) EncodeFromNum(id int64) (string, error) {
code, err := generateCode(id, c.Base, c.Length, c.ConvertTable)
if err != nil {
return "", err
}
return code, nil
}
func (c *Converter) DecodeFromCode(code string) (int64, error) {
var result int64 = 0
length := len(code)
for i := 0; i < length; i++ {
char := string(code[i])
index := -1
for j, v := range c.ConvertTable {
if v == char {
index = j
break
}
}
if index >= 0 {
result = result*int64(c.Base) + int64(index)
} else {
return 0, fmt.Errorf("character not found in convert table")
}
}
return result, nil
}
// generateCode 從 UID 生成 referralCode
func generateCode(id int64, base int, length int, convertTable []string) (string, error) {
maxReferralUIDBoundary := int64(math.Pow(float64(len(ConvertTable)), float64(DefaultCodeLen)))
if id > maxReferralUIDBoundary {
return "", fmt.Errorf("encode out of range")
}
encoded := encodeToBase(id, base, length, convertTable)
return encoded, nil
}
func encodeToBase(num int64, base int, length int, convertTable []string) string {
result := ""
for num > 0 {
index := num % int64(base)
result = convertTable[index] + result
num /= int64(base)
}
if len(result) < length {
result = strings.Repeat(convertTable[0], length-len(result)) + result
}
return result
}
func MustConverter(base int, length int, convertTable []string) ConvertUseCase {
return &Converter{
Base: base,
Length: length,
ConvertTable: convertTable,
}
}