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 }