podman
230 строк · 7.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 goutils18
19import (20"crypto/rand"21"fmt"22"math"23"math/big"24"unicode"25)
26
27/*
28CryptoRandomNonAlphaNumeric creates a random string whose length is the number of characters specified.
29Characters will be chosen from the set of all characters (ASCII/Unicode values between 0 to 2,147,483,647 (math.MaxInt32)).
30
31Parameter:
32count - the length of random string to create
33
34Returns:
35string - the random string
36error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
37*/
38func CryptoRandomNonAlphaNumeric(count int) (string, error) {39return CryptoRandomAlphaNumericCustom(count, false, false)40}
41
42/*
43CryptoRandomAscii creates a random string whose length is the number of characters specified.
44Characters will be chosen from the set of characters whose ASCII value is between 32 and 126 (inclusive).
45
46Parameter:
47count - the length of random string to create
48
49Returns:
50string - the random string
51error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
52*/
53func CryptoRandomAscii(count int) (string, error) {54return CryptoRandom(count, 32, 127, false, false)55}
56
57/*
58CryptoRandomNumeric creates a random string whose length is the number of characters specified.
59Characters will be chosen from the set of numeric characters.
60
61Parameter:
62count - the length of random string to create
63
64Returns:
65string - the random string
66error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
67*/
68func CryptoRandomNumeric(count int) (string, error) {69return CryptoRandom(count, 0, 0, false, true)70}
71
72/*
73CryptoRandomAlphabetic creates a random string whose length is the number of characters specified.
74Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
75
76Parameters:
77count - the length of random string to create
78letters - if true, generated string may include alphabetic characters
79numbers - if true, generated string may include numeric characters
80
81Returns:
82string - the random string
83error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
84*/
85func CryptoRandomAlphabetic(count int) (string, error) {86return CryptoRandom(count, 0, 0, true, false)87}
88
89/*
90CryptoRandomAlphaNumeric creates a random string whose length is the number of characters specified.
91Characters will be chosen from the set of alpha-numeric characters.
92
93Parameter:
94count - the length of random string to create
95
96Returns:
97string - the random string
98error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
99*/
100func CryptoRandomAlphaNumeric(count int) (string, error) {101return CryptoRandom(count, 0, 0, true, true)102}
103
104/*
105CryptoRandomAlphaNumericCustom creates a random string whose length is the number of characters specified.
106Characters will be chosen from the set of alpha-numeric characters as indicated by the arguments.
107
108Parameters:
109count - the length of random string to create
110letters - if true, generated string may include alphabetic characters
111numbers - if true, generated string may include numeric characters
112
113Returns:
114string - the random string
115error - an error stemming from an invalid parameter within underlying function, CryptoRandom(...)
116*/
117func CryptoRandomAlphaNumericCustom(count int, letters bool, numbers bool) (string, error) {118return CryptoRandom(count, 0, 0, letters, numbers)119}
120
121/*
122CryptoRandom creates a random string based on a variety of options, using using golang's crypto/rand source of randomness.
123If the parameters start and end are both 0, start and end are set to ' ' and 'z', the ASCII printable characters, will be used,
124unless letters and numbers are both false, in which case, start and end are set to 0 and math.MaxInt32, respectively.
125If chars is not nil, characters stored in chars that are between start and end are chosen.
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 invalid parameters: if count < 0; or the provided chars array is empty; or end <= start; or end > len(chars)
138*/
139func CryptoRandom(count int, start int, end int, letters bool, numbers bool, chars ...rune) (string, error) {140if count == 0 {141return "", nil142} else if count < 0 {143err := fmt.Errorf("randomstringutils illegal argument: Requested random string length %v is less than 0.", count) // equiv to err := errors.New("...")144return "", err145}146if chars != nil && len(chars) == 0 {147err := fmt.Errorf("randomstringutils illegal argument: The chars array must not be empty")148return "", err149}150
151if start == 0 && end == 0 {152if chars != nil {153end = len(chars)154} else {155if !letters && !numbers {156end = math.MaxInt32157} else {158end = 'z' + 1159start = ' '160}161}162} else {163if end <= start {164err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) must be greater than start (%v)", end, start)165return "", err166}167
168if chars != nil && end > len(chars) {169err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) cannot be greater than len(chars) (%v)", end, len(chars))170return "", err171}172}173
174buffer := make([]rune, count)175gap := end - start176
177// high-surrogates range, (\uD800-\uDBFF) = 55296 - 56319178// low-surrogates range, (\uDC00-\uDFFF) = 56320 - 57343179
180for count != 0 {181count--182var ch rune183if chars == nil {184ch = rune(getCryptoRandomInt(gap) + int64(start))185} else {186ch = chars[getCryptoRandomInt(gap)+int64(start)]187}188
189if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers {190if ch >= 56320 && ch <= 57343 { // low surrogate range191if count == 0 {192count++193} else {194// Insert low surrogate195buffer[count] = ch196count--197// Insert high surrogate198buffer[count] = rune(55296 + getCryptoRandomInt(128))199}200} else if ch >= 55296 && ch <= 56191 { // High surrogates range (Partial)201if count == 0 {202count++203} else {204// Insert low surrogate205buffer[count] = rune(56320 + getCryptoRandomInt(128))206count--207// Insert high surrogate208buffer[count] = ch209}210} else if ch >= 56192 && ch <= 56319 {211// private high surrogate, skip it212count++213} else {214// not one of the surrogates*215buffer[count] = ch216}217} else {218count++219}220}221return string(buffer), nil222}
223
224func getCryptoRandomInt(count int) int64 {225nBig, err := rand.Int(rand.Reader, big.NewInt(int64(count)))226if err != nil {227panic(err)228}229return nBig.Int64()230}
231