diff --git a/uniuri.go b/uniuri.go index 0e9ee1b..41e5719 100644 --- a/uniuri.go +++ b/uniuri.go @@ -48,14 +48,18 @@ func NewLen(length int) string { func NewLenChars(length int, chars []byte) string { b := make([]byte, length) r := make([]byte, length+(length/4)) // storage for random bytes. - clen := byte(len(chars)) - maxrb := byte(256 - (256 % len(chars))) + clen := len(chars) + if clen > 256 { + panic("uniuri: maximum length of charset for NewLenChars is 256") + } + maxrb := 256 - (256 % len(chars)) i := 0 for { if _, err := io.ReadFull(rand.Reader, r); err != nil { panic("error reading from random source: " + err.Error()) } - for _, c := range r { + for _, byte := range r { + c := int(byte) if c > maxrb { // Skip this number to avoid modulo bias. continue diff --git a/uniuri_test.go b/uniuri_test.go index ff9a83d..17b3ba1 100644 --- a/uniuri_test.go +++ b/uniuri_test.go @@ -50,4 +50,20 @@ func TestNewLenChars(t *testing.T) { } // Check that only allowed characters are present validateChars(t, u, chars) + + // Check that two generated strings are different + u2 := NewLenChars(length, chars) + if u == u2 { + t.Fatalf("not unique: %q and %q", u, u2) + } +} + +func TestNewLenCharsMaxLength(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fatal("didn't panic") + } + }() + chars := make([]byte, 257) + NewLenChars(32, chars) }