github.com/jxskiss/gopkg@v0.17.3/strutil/random.go (about)

     1  package strutil
     2  
     3  import (
     4  	cryptorand "crypto/rand"
     5  	"math/big"
     6  	"math/rand"
     7  	"time"
     8  	"unsafe"
     9  )
    10  
    11  func init() {
    12  	rand.Seed(time.Now().UnixNano())
    13  }
    14  
    15  func random(table string, length int) []byte {
    16  	buf := make([]byte, length)
    17  	max := len(table)
    18  	for i := range buf {
    19  		buf[i] = table[rand.Intn(max)]
    20  	}
    21  	return buf
    22  }
    23  
    24  func Random(table string, length int) string {
    25  	buf := random(table, length)
    26  	return b2s(buf)
    27  }
    28  
    29  // RandLetters returns a random string containing lowercase and uppercase
    30  // alphabetic characters.
    31  func RandLetters(length int) string {
    32  	return Random(Letters, length)
    33  }
    34  
    35  // RandLowerLetters returns a random string containing only lowercase
    36  // alphabetic characters.
    37  func RandLowerLetters(length int) string {
    38  	return Random(LowerLetters, length)
    39  }
    40  
    41  // RandUpperLetters returns a random string containing only uppercase
    42  // alphabetic characters.
    43  func RandUpperLetters(length int) string {
    44  	return Random(UpperLetters, length)
    45  }
    46  
    47  // RandDigits returns a random string containing only digit numbers, the
    48  // first character is guaranteed to be not zero.
    49  func RandDigits(length int) string {
    50  	out := random(Digits, length)
    51  	if out[0] == '0' {
    52  		out[0] = Digits[rand.Intn(9)+1] // 1-9, no zero
    53  	}
    54  	return b2s(out)
    55  }
    56  
    57  // RandAlphaDigits returns a random string containing only characters from
    58  // lowercase, uppercase alphabetic characters or digit numbers.
    59  func RandAlphaDigits(length int) string {
    60  	return Random(AlphaDigits, length)
    61  }
    62  
    63  func cryptoRandom(table string, length int) []byte {
    64  	buf := make([]byte, length)
    65  	max := int64(len(table))
    66  	for i := range buf {
    67  		n := big.NewInt(max)
    68  		n, err := cryptorand.Int(cryptorand.Reader, n)
    69  		if err != nil {
    70  			panic(err)
    71  		}
    72  		buf[i] = table[n.Int64()]
    73  	}
    74  	return buf
    75  }
    76  
    77  // RandPassword returns a random string containing lowercase and uppercase
    78  // alphabetic characters to be used as a password.
    79  func RandPassword(length int) string {
    80  	buf := cryptoRandom(AlphaDigits, length)
    81  	return b2s(buf)
    82  }
    83  
    84  // RandStrongPassword returns a random string containing lowercase and uppercase
    85  // alphabetic characters and punctuation to be used as a password.
    86  func RandStrongPassword(length int) string {
    87  	table := AlphaDigits + PunctNoEscape
    88  	buf := cryptoRandom(table, length)
    89  	return b2s(buf)
    90  }
    91  
    92  func b2s(b []byte) string {
    93  	return *(*string)(unsafe.Pointer(&b))
    94  }