54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package code
|
||
|
||
import (
|
||
"fmt"
|
||
"samba/util/model"
|
||
"samba/util/util"
|
||
"strings"
|
||
)
|
||
|
||
// 定义字符集,排除L、O、I、0、1
|
||
var charset = []rune("ABCDEFGHJKMNPQRSTUVWXYZ23456789")
|
||
|
||
// RedeemCodeGenerator 兑换码生成器
|
||
type RedeemCodeGenerator struct {
|
||
}
|
||
|
||
// UnsafeNext 生成下一个兑换码
|
||
func (g RedeemCodeGenerator) UnsafeNext() string {
|
||
var b strings.Builder
|
||
for i := 0; i < 8; i++ {
|
||
b.WriteRune(util.RandChoice(charset))
|
||
}
|
||
return b.String()
|
||
}
|
||
|
||
// Next 生成下一个兑换码,附带去重判断
|
||
func (g RedeemCodeGenerator) Next() string {
|
||
op := model.NewRedeemCodeOp()
|
||
code := g.UnsafeNext()
|
||
for op.IsExist(code) {
|
||
code = g.UnsafeNext()
|
||
}
|
||
return code
|
||
}
|
||
|
||
// IsValid 验证兑换码是否合法
|
||
func (g RedeemCodeGenerator) IsValid(code string) error {
|
||
if len(code) != 8 {
|
||
return fmt.Errorf("%w:length must be 8", ErrCodeFormat)
|
||
}
|
||
charsetMp := make(map[rune]struct{}, len(charset))
|
||
for _, r := range charset {
|
||
charsetMp[r] = struct{}{}
|
||
}
|
||
for _, r := range code {
|
||
if _, ok := charsetMp[r]; !ok {
|
||
return fmt.Errorf("%w: invalid char %s", ErrCodeFormat, string(r))
|
||
}
|
||
}
|
||
|
||
return nil
|
||
|
||
}
|