-
Notifications
You must be signed in to change notification settings - Fork 45
/
string.go
88 lines (78 loc) · 2.01 KB
/
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
87
88
package utils
import (
"crypto/rand"
"math"
"math/big"
"strings"
)
const alphaLowers string = "abcdefghijklmnopqrstuvwxyz"
var (
alphaUppers = strings.ToUpper(alphaLowers)
maxInt32 = big.NewInt(math.MaxInt32)
fiftyFityChance = big.NewInt(2)
)
// RandomAlphaString returns a random alphabetic string of the given size.
// Note(erd): all random strings are subject to modulus bias; hope that
// does not matter to you.
func RandomAlphaString(size int) string {
if size < 0 {
return ""
}
chars := make([]byte, 0, size)
for i := 0; i < size; i++ {
valBig, err := rand.Int(rand.Reader, maxInt32)
if err != nil {
panic(err)
}
val := int(valBig.Int64())
chance, err := rand.Int(rand.Reader, fiftyFityChance)
if err != nil {
panic(err)
}
switch chance.Int64() {
case 0:
chars = append(chars, alphaLowers[val%len(alphaLowers)])
case 1:
chars = append(chars, alphaUppers[val%len(alphaUppers)])
}
}
return string(chars)
}
// StringSet represents a mathematical set of string.
type StringSet map[string]struct{}
// NewStringSet returns a new string set from the given series of values
// where duplicates are okay.
func NewStringSet(values ...string) StringSet {
set := make(StringSet, len(values))
for _, val := range values {
set[val] = struct{}{}
}
return set
}
// Add adds the value to the StringSet
// if the value already exists it will be a no-op.
func (ss StringSet) Add(value string) {
ss[value] = struct{}{}
}
// Remove removes the value from the StringSet
// If the value doesn't exist it will be a no-op.
func (ss StringSet) Remove(value string) {
delete(ss, value)
}
// ToList converts the set into a list of strings.
func (ss StringSet) ToList() []string {
list := make([]string, len(ss))
i := 0
for key := range ss {
list[i] = key
i++
}
return list
}
// StringSliceRemove removes an element from the slice at the given position.
func StringSliceRemove(from []string, at int) []string {
if at >= len(from) {
return from
}
return append(from[:at], from[at+1:]...)
}