Skip to content

Commit

Permalink
重构: randx.RandCode 代码 (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
dxyinme authored Jan 14, 2024
1 parent eba89e1 commit 4628cd1
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# 开发中
- [syncx: 支持分key加锁](https://github.com/ecodeclub/ekit/pull/224)
- [syncx: 添加具有最大申请次数限制的LimitPool](https://github.com/ecodeclub/ekit/pull/233)
- [tuple: 增加Pair的实现](https://github.com/ecodeclub/ekit/pull/237)
- [randx: 重构randx.RandCode的代码,增加对特殊字符的支持](https://github.com/ecodeclub/ekit/pull/241)

# v0.0.8
- [atomicx: 泛型封装 atomic.Value](https://github.com/gotomicro/ekit/pull/101)
Expand Down
103 changes: 83 additions & 20 deletions randx/rand_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,99 @@ package randx
import (
"errors"
"math/rand"

"github.com/ecodeclub/ekit/tuple/pair"
)

var ERRTYPENOTSUPPORTTED = errors.New("ekit:不支持的类型")
var (
errTypeNotSupported = errors.New("ekit:不支持的类型")
errLengthLessThanZero = errors.New("ekit:长度必须大于等于0")
)

type TYPE int

const (
TYPE_DEFAULT TYPE = 0 //默认类型
TYPE_DIGIT TYPE = 1 //数字//
TYPE_LETTER TYPE = 2 //小写字母
TYPE_CAPITAL TYPE = 3 //大写字母
TYPE_MIXED TYPE = 4 //数字+字母混合
// 数字
TYPE_DIGIT TYPE = 1
// 小写字母
TYPE_LOWERCASE TYPE = 1 << 1
TYPE_LETTER TYPE = TYPE_LOWERCASE
// 大写字母
TYPE_UPPERCASE TYPE = 1 << 2
TYPE_CAPITAL TYPE = TYPE_UPPERCASE
// 特殊符号
TYPE_SPECIAL TYPE = 1 << 3
// 混合类型
TYPE_MIXED = (TYPE_DIGIT | TYPE_UPPERCASE | TYPE_LOWERCASE | TYPE_SPECIAL)

// 数字字符组
CHARSET_DIGIT = "0123456789"
// 小写字母字符组
CHARSET_LOWERCASE = "abcdefghijklmnopqrstuvwxyz"
CHARSET_LETTER = CHARSET_LOWERCASE
// 大写字母字符组
CHARSET_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CHARSET_CAPITAL = CHARSET_UPPERCASE
// 特殊字符数组
CHARSET_SPECIAL = " ~!@#$%^&*()_+-=[]{};'\\:\"|,./<>?"
)

var (
// 只限于randx包内部使用
typeCharsetPairs = []pair.Pair[TYPE, string]{
pair.NewPair(TYPE_DIGIT, CHARSET_DIGIT),
pair.NewPair(TYPE_LOWERCASE, CHARSET_LOWERCASE),
pair.NewPair(TYPE_UPPERCASE, CHARSET_UPPERCASE),
pair.NewPair(TYPE_SPECIAL, CHARSET_SPECIAL),
}
)

// RandCode 根据传入的长度和类型生成随机字符串,这个方法目前可以生成数字、字母、数字+字母的随机字符串
// RandCode 根据传入的长度和类型生成随机字符串
// 请保证输入的 length >= 0,否则会返回 errLengthLessThanZero
// 请保证输入的 typ 的取值范围在 (0, type.MIXED] 内,否则会返回 errTypeNotSupported
func RandCode(length int, typ TYPE) (string, error) {
switch typ {
case TYPE_DEFAULT:
fallthrough
case TYPE_DIGIT:
return generate("0123456789", length, 4), nil
case TYPE_LETTER:
return generate("abcdefghijklmnopqrstuvwxyz", length, 5), nil
case TYPE_CAPITAL:
return generate("ABCDEFGHIJKLMNOPQRSTUVWXYZ", length, 5), nil
case TYPE_MIXED:
return generate("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", length, 7), nil
default:
return "", ERRTYPENOTSUPPORTTED
if length < 0 {
return "", errLengthLessThanZero
}
if length == 0 {
return "", nil
}
if typ > TYPE_MIXED {
return "", errTypeNotSupported
}
charset := ""
for _, p := range typeCharsetPairs {
if (typ & p.Key) == p.Key {
charset += p.Value
}
}
return RandStrByCharset(length, charset)
}

// 根据传入的长度和字符集生成随机字符串
// 请保证输入的 length >= 0,否则会返回 errLengthLessThanZero
// 请保证输入的字符集不为空字符串,否则会返回 errTypeNotSupported
// 字符集内部字符可以无序或重复
func RandStrByCharset(length int, charset string) (string, error) {
if length < 0 {
return "", errLengthLessThanZero
}
if length == 0 {
return "", nil
}
charsetSize := len(charset)
if charsetSize == 0 {
return "", errTypeNotSupported
}
return generate(charset, length, getFirstMask(charsetSize)), nil
}

func getFirstMask(charsetSize int) int {
bits := 0
for charsetSize > ((1 << bits) - 1) {
bits++
}
return bits
}

// generate 根据传入的随机源和长度生成随机字符串,一次随机,多次使用
Expand Down
Loading

0 comments on commit 4628cd1

Please sign in to comment.