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
|
|||
|
|
|||
|
}
|