Skip to content

Commit 44a7dd3

Browse files
committed
#49 fix: generating with size 1
Backport updated `getMask` func from v2 to fix inifinite loop if alphabet size is 1. Fixes: #49
1 parent 554e6f8 commit 44a7dd3

File tree

2 files changed

+14
-22
lines changed

2 files changed

+14
-22
lines changed

gonanoid.go

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
)
99

1010
var defaultAlphabet = []rune("_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
11+
1112
const (
1213
defaultSize = 21
1314
defaultMaskSize = 5
@@ -19,26 +20,13 @@ type Generator func([]byte) (int, error)
1920
// BytesGenerator is the default bytes generator
2021
var BytesGenerator Generator = rand.Read
2122

22-
func initMasks(params ...int) []uint {
23-
var size int
24-
if len(params) == 0 {
25-
size = defaultMaskSize
26-
} else {
27-
size = params[0]
28-
}
29-
masks := make([]uint, size)
30-
for i := 0; i < size; i++ {
31-
shift := 3 + i
32-
masks[i] = (2 << uint(shift)) - 1
33-
}
34-
return masks
35-
}
36-
37-
func getMask(alphabet []rune, masks []uint) int {
38-
for i := 0; i < len(masks); i++ {
39-
curr := int(masks[i])
40-
if curr >= len(alphabet)-1 {
41-
return curr
23+
// getMask generates bit mask used to obtain bits from the random bytes that are used to get index of random character
24+
// from the alphabet. Example: if the alphabet has 6 = (110)_2 characters it is sufficient to use mask 7 = (111)_2
25+
func getMask(alphabetSize int) int {
26+
for i := 1; i <= 8; i++ {
27+
mask := (2 << uint(i)) - 1
28+
if mask >= alphabetSize-1 {
29+
return mask
4230
}
4331
}
4432
return 0
@@ -55,8 +43,7 @@ func Generate(rawAlphabet string, size int) (string, error) {
5543
return "", fmt.Errorf("size must be positive integer")
5644
}
5745

58-
masks := initMasks(size)
59-
mask := getMask(alphabet, masks)
46+
mask := getMask(len(alphabet))
6047
ceilArg := 1.6 * float64(mask*size) / float64(len(alphabet))
6148
step := int(math.Ceil(ceilArg))
6249

gonanoid_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,8 @@ func TestID(t *testing.T) {
170170
})
171171
}
172172
}
173+
174+
func TestSize1(t *testing.T) {
175+
prefixAlphabet := "abcdefghijklmnopqrstuvwxyz"
176+
_, _ = Generate(prefixAlphabet, 1)
177+
}

0 commit comments

Comments
 (0)