123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- // Copyright 2019 github.com. All rights reserved.
- // Use of this source code is governed by github.com.
- package util
- import (
- "math/rand"
- "time"
- )
- const (
- alpha = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ" // 字母
- number = "1234567890" // 数字
- punctuation = "!@#$%^&*()_+[]{};':\",./<>?" // 符号
- alphaNumber = number + alpha // 字母+数字
- alphaNumberPunctuation = alphaNumber + punctuation // 字母+数字+符号
- )
- // 提供几种常见的随机字符组合方式
- var (
- bytesAlpha = []byte(alpha)
- bytesNumber = []byte(number)
- bytesPunctuation = []byte(punctuation)
- bytesAlphaNumber = []byte(alphaNumber)
- bytesAlphaNumberPunctuation = []byte(alphaNumberPunctuation)
- )
- // 供全局函数使用的随机函数生成。
- // RandBytes 和 String 依赖此项。
- var random = rand.New(rand.NewSource(time.Now().UnixNano()))
- // RandAlpha 产生随机字母串
- func RandAlpha(min, max int) string {
- return string(RandBytes(min, max, bytesAlpha))
- }
- // RandNumber 产生随机数字串
- func RandNumber(min, max int) string {
- return string(RandBytes(min, max, bytesNumber))
- }
- // RandPunctuation 产生随机符号串
- func RandPunctuation(min, max int) string {
- return string(RandBytes(min, max, bytesPunctuation))
- }
- // RandAlphaNumber 产生随机字母+数字组合串
- func RandAlphaNumber(min, max int) string {
- return string(RandBytes(min, max, bytesAlphaNumber))
- }
- // RandAlphaNumberPunctuation 产生随机字母+数字组合串
- func RandAlphaNumberPunctuation(min, max int) string {
- return string(RandBytes(min, max, bytesAlphaNumberPunctuation))
- }
- // Seed 手动指定一个随机种子,默认情况下使用当前包初始化时的时间戳作为随机种子。
- // RandBytes 和 String 依赖此项。但是 Rands 有专门的随机函数,不受此影响。
- func Seed(seed int64) {
- random = rand.New(rand.NewSource(seed))
- }
- // RandBytes 产生随机字符数组,其长度为[min, max)。
- // bs 所有的随机字符串从此处取。
- func RandBytes(min, max int, bs []byte) []byte {
- checkArgs(min, max, bs)
- return genBytes(random, min+random.Intn(max-min), bs)
- }
- // RandString 产生一个随机字符串,其长度为[min, max)。
- // bs 可用的随机字符串。
- func RandString(min, max int, bs []byte) string {
- return string(RandBytes(min, max, bs))
- }
- // Rands 提供了对参数的简单包装,方便用户批量产生相同的类型的随机字符串。
- type Rands struct {
- random *rand.Rand
- min, max int
- bytes []byte
- hasBuffer bool
- channel chan []byte
- done chan struct{}
- }
- // New 声明一个 Rands 变量。
- //
- // seed 随机种子,若为 0 表示使用当前时间作为随机种子。
- // bufferSize 缓存的随机字符串数量,若为 0,表示不缓存。
- func New(seed int64, bufferSize, min, max int, bs []byte) (*Rands, error) {
- checkArgs(min, max, bs)
- if seed == 0 {
- seed = time.Now().UnixNano()
- }
- ret := &Rands{
- random: rand.New(rand.NewSource(seed)),
- min: min,
- max: max,
- bytes: bs,
- hasBuffer: bufferSize > 0,
- done: make(chan struct{}),
- }
- if ret.hasBuffer {
- ret.channel = make(chan []byte, bufferSize)
- go func() {
- for {
- select {
- case <-ret.done:
- close(ret.channel)
- return
- case ret.channel <- genBytes(ret.random, min+ret.random.Intn(max-min), bs):
- }
- } // end ofr
- }()
- }
- return ret, nil
- }
- // Seed 重新指定随机种子。
- func (r *Rands) Seed(seed int64) {
- r.random.Seed(seed)
- }
- // Bytes 产生随机字符数组,功能与全局函数Bytes()相同,但参数通过New()预先指定。
- func (r *Rands) Bytes() []byte {
- if r.hasBuffer {
- if ret, ok := <-r.channel; ok {
- return ret
- }
- return nil
- }
- return genBytes(r.random, r.min+r.random.Intn(r.max-r.min), r.bytes)
- }
- // String 产生一个随机字符串,功能与全局函数 String() 相同,但参数通过 New() 预先指定。
- func (r *Rands) String() string {
- if r.hasBuffer {
- return string(<-r.channel)
- }
- return string(r.Bytes())
- }
- // Stop 停止产生随机字符串
- func (r *Rands) Stop() {
- r.done <- struct{}{}
- }
- // 生成指定指定长度的随机字符数组
- func genBytes(r *rand.Rand, l int, bs []byte) []byte {
- ret := make([]byte, l, l)
- for i := 0; i < l; i++ {
- index := r.Intn(len(bs))
- ret[i] = bs[index]
- }
- return ret
- }
- // 检测各个参数是否合法
- func checkArgs(min, max int, bs []byte) {
- if min <= 0 {
- panic("min 值必须大于 0")
- }
- if max <= min {
- panic("max 必须大于 min")
- }
- if len(bs) == 0 {
- panic("无效的 bs 参数")
- }
- }
|