-
Notifications
You must be signed in to change notification settings - Fork 7
/
random-string.go
86 lines (69 loc) · 1.73 KB
/
random-string.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package handy
import (
"log"
"math/rand"
"unicode"
"unicode/utf8"
)
// RandomString generates a string sequence based on given params/rules
func RandomString(minLen, maxLen int, allowUnicode, allowNumbers, allowSymbols, allowSpaces bool) string {
switch {
case minLen > maxLen:
log.Println("handy.RandomString(minLen is greater than maxLen)")
return ""
case maxLen == 0:
log.Println("handy.RandomString(maxLen should be greater than zero)")
return ""
case minLen == 0:
minLen = 1
}
// If minLen==maxLen, force fixed size string
strLen := maxLen
// but if minLen<>maxLen, string length must be between minLen and maxLen
if minLen < maxLen {
strLen = rand.Intn(maxLen-minLen) + minLen
}
str := make([]rune, strLen)
// Checks if the space is at begining or at string end
// to avoid leading or trailing spaces
firstOrLast := func(i int) bool {
return i == 0 || i == strLen-1
}
const minimumPrintableRune = 32
var (
asciiTable = []rune(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
asciiTableLen = int32(len(asciiTable))
r rune
)
for i := 0; i < strLen; {
if !allowUnicode {
p := rand.Int31n(asciiTableLen)
r = asciiTable[p]
} else {
r = rand.Int31n(utf8.MaxRune-minimumPrintableRune) + minimumPrintableRune
}
switch {
case !unicode.IsPrint(r):
continue
case unicode.IsLetter(r):
str[i] = r
i++
case unicode.IsNumber(r) || unicode.IsDigit(r):
if allowNumbers {
str[i] = r
i++
}
case unicode.IsSymbol(r) || unicode.IsPunct(r):
if allowSymbols {
str[i] = r
i++
}
case unicode.IsSpace(r):
if allowSpaces && !firstOrLast(i) {
str[i] = r
i++
}
}
}
return string(str)
}