70 lines
1.2 KiB
Go
70 lines
1.2 KiB
Go
|
package random
|
||
|
|
||
|
import (
|
||
|
"math/rand"
|
||
|
"time"
|
||
|
"unsafe"
|
||
|
)
|
||
|
|
||
|
type Mode int // 随机数模式
|
||
|
|
||
|
const (
|
||
|
Letter Mode = iota
|
||
|
Number
|
||
|
LetterNumber
|
||
|
LetterHex
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
numbers = "0123456789"
|
||
|
lettersHex = "0123456789abcdef"
|
||
|
letterIdBit = 6
|
||
|
letterIdxMask = 1<<letterIdBit - 1
|
||
|
letterIdxMax = 63 / letterIdBit
|
||
|
)
|
||
|
|
||
|
func StrRandom(n int64) string {
|
||
|
return Random(n, Letter)
|
||
|
}
|
||
|
|
||
|
func NumRandom(n int64) string {
|
||
|
return Random(n, Number)
|
||
|
}
|
||
|
|
||
|
func Random(n int64, mode ...Mode) string {
|
||
|
var baseStr string
|
||
|
mode = append(mode, LetterNumber)
|
||
|
switch mode[0] {
|
||
|
case LetterHex:
|
||
|
baseStr = lettersHex
|
||
|
case Letter:
|
||
|
baseStr = letters
|
||
|
case Number:
|
||
|
baseStr = numbers
|
||
|
case LetterNumber:
|
||
|
fallthrough
|
||
|
default:
|
||
|
baseStr = letters + numbers
|
||
|
}
|
||
|
return random(n, baseStr)
|
||
|
}
|
||
|
|
||
|
func random(n int64, baseStr string) string {
|
||
|
|
||
|
var src = rand.NewSource(time.Now().UnixNano())
|
||
|
b := make([]byte, n)
|
||
|
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
|
||
|
if remain == 0 {
|
||
|
cache, remain = src.Int63(), letterIdxMax
|
||
|
}
|
||
|
if idx := int(cache & letterIdxMask); idx < len(baseStr) {
|
||
|
b[i] = baseStr[idx]
|
||
|
i--
|
||
|
}
|
||
|
cache >>= letterIdBit
|
||
|
remain--
|
||
|
}
|
||
|
return *(*string)(unsafe.Pointer(&b))
|
||
|
}
|