podman
248 строк · 8.3 Кб
1/*
2Copyright 2014 Alexander Okoli
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package goutils
18
19import (
20"fmt"
21"math"
22"math/rand"
23"time"
24"unicode"
25)
26
27// RANDOM provides the time-based seed used to generate random numbers
28var RANDOM = rand.New(rand.NewSource(time.Now().UnixNano()))
29
30/*
31RandomNonAlphaNumeric creates a random string whose length is the number of characters specified.
32Characters will be chosen from the set of all characters (ASCII/Unicode values between 0 to 2,147,483,647 (math.MaxInt32)).
33
34Parameter:
35count - the length of random string to create
36
37Returns:
38string - the random string
39error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
40*/
41func RandomNonAlphaNumeric(count int) (string, error) {
42return RandomAlphaNumericCustom(count, false, false)
43}
44
45/*
46RandomAscii creates a random string whose length is the number of characters specified.
47Characters will be chosen from the set of characters whose ASCII value is between 32 and 126 (inclusive).
48
49Parameter:
50count - the length of random string to create
51
52Returns:
53string - the random string
54error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
55*/
56func RandomAscii(count int) (string, error) {
57return Random(count, 32, 127, false, false)
58}
59
60/*
61RandomNumeric creates a random string whose length is the number of characters specified.
62Characters will be chosen from the set of numeric characters.
63
64Parameter:
65count - the length of random string to create
66
67Returns:
68string - the random string
69error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
70*/
71func RandomNumeric(count int) (string, error) {
72return Random(count, 0, 0, false, true)
73}
74
75/*
76RandomAlphabetic creates a random string whose length is the number of characters specified.
77Characters will be chosen from the set of alphabetic characters.
78
79Parameters:
80count - the length of random string to create
81
82Returns:
83string - the random string
84error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
85*/
86func RandomAlphabetic(count int) (string, error) {
87return Random(count, 0, 0, true, false)
88}
89
90/*
91RandomAlphaNumeric creates a random string whose length is the number of characters specified.
92Characters will be chosen from the set of alpha-numeric characters.
93
94Parameter:
95count - the length of random string to create
96
97Returns:
98string - the random string
99error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
100*/
101func RandomAlphaNumeric(count int) (string, error) {
102return Random(count, 0, 0, true, true)
103}
104
105/*
106RandomAlphaNumericCustom creates a random string whose length is the number of characters specified.
107Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
108
109Parameters:
110count - the length of random string to create
111letters - if true, generated string may include alphabetic characters
112numbers - if true, generated string may include numeric characters
113
114Returns:
115string - the random string
116error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
117*/
118func RandomAlphaNumericCustom(count int, letters bool, numbers bool) (string, error) {
119return Random(count, 0, 0, letters, numbers)
120}
121
122/*
123Random creates a random string based on a variety of options, using default source of randomness.
124This method has exactly the same semantics as RandomSeed(int, int, int, bool, bool, []char, *rand.Rand), but
125instead of using an externally supplied source of randomness, it uses the internal *rand.Rand instance.
126
127Parameters:
128count - the length of random string to create
129start - the position in set of chars (ASCII/Unicode int) to start at
130end - the position in set of chars (ASCII/Unicode int) to end before
131letters - if true, generated string may include alphabetic characters
132numbers - if true, generated string may include numeric characters
133chars - the set of chars to choose randoms from. If nil, then it will use the set of all chars.
134
135Returns:
136string - the random string
137error - an error stemming from an invalid parameter within underlying function, RandomSeed(...)
138*/
139func Random(count int, start int, end int, letters bool, numbers bool, chars ...rune) (string, error) {
140return RandomSeed(count, start, end, letters, numbers, chars, RANDOM)
141}
142
143/*
144RandomSeed creates a random string based on a variety of options, using supplied source of randomness.
145If the parameters start and end are both 0, start and end are set to ' ' and 'z', the ASCII printable characters, will be used,
146unless letters and numbers are both false, in which case, start and end are set to 0 and math.MaxInt32, respectively.
147If chars is not nil, characters stored in chars that are between start and end are chosen.
148This method accepts a user-supplied *rand.Rand instance to use as a source of randomness. By seeding a single *rand.Rand instance
149with a fixed seed and using it for each call, the same random sequence of strings can be generated repeatedly and predictably.
150
151Parameters:
152count - the length of random string to create
153start - the position in set of chars (ASCII/Unicode decimals) to start at
154end - the position in set of chars (ASCII/Unicode decimals) to end before
155letters - if true, generated string may include alphabetic characters
156numbers - if true, generated string may include numeric characters
157chars - the set of chars to choose randoms from. If nil, then it will use the set of all chars.
158random - a source of randomness.
159
160Returns:
161string - the random string
162error - an error stemming from invalid parameters: if count < 0; or the provided chars array is empty; or end <= start; or end > len(chars)
163*/
164func RandomSeed(count int, start int, end int, letters bool, numbers bool, chars []rune, random *rand.Rand) (string, error) {
165
166if count == 0 {
167return "", nil
168} else if count < 0 {
169err := fmt.Errorf("randomstringutils illegal argument: Requested random string length %v is less than 0.", count) // equiv to err := errors.New("...")
170return "", err
171}
172if chars != nil && len(chars) == 0 {
173err := fmt.Errorf("randomstringutils illegal argument: The chars array must not be empty")
174return "", err
175}
176
177if start == 0 && end == 0 {
178if chars != nil {
179end = len(chars)
180} else {
181if !letters && !numbers {
182end = math.MaxInt32
183} else {
184end = 'z' + 1
185start = ' '
186}
187}
188} else {
189if end <= start {
190err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) must be greater than start (%v)", end, start)
191return "", err
192}
193
194if chars != nil && end > len(chars) {
195err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) cannot be greater than len(chars) (%v)", end, len(chars))
196return "", err
197}
198}
199
200buffer := make([]rune, count)
201gap := end - start
202
203// high-surrogates range, (\uD800-\uDBFF) = 55296 - 56319
204// low-surrogates range, (\uDC00-\uDFFF) = 56320 - 57343
205
206for count != 0 {
207count--
208var ch rune
209if chars == nil {
210ch = rune(random.Intn(gap) + start)
211} else {
212ch = chars[random.Intn(gap)+start]
213}
214
215if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers {
216if ch >= 56320 && ch <= 57343 { // low surrogate range
217if count == 0 {
218count++
219} else {
220// Insert low surrogate
221buffer[count] = ch
222count--
223// Insert high surrogate
224buffer[count] = rune(55296 + random.Intn(128))
225}
226} else if ch >= 55296 && ch <= 56191 { // High surrogates range (Partial)
227if count == 0 {
228count++
229} else {
230// Insert low surrogate
231buffer[count] = rune(56320 + random.Intn(128))
232count--
233// Insert high surrogate
234buffer[count] = ch
235}
236} else if ch >= 56192 && ch <= 56319 {
237// private high surrogate, skip it
238count++
239} else {
240// not one of the surrogates*
241buffer[count] = ch
242}
243} else {
244count++
245}
246}
247return string(buffer), nil
248}
249