81 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			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,
 | |
| 	}
 | |
| }
 |