Fix for alphabets of 256 characters.

Also, panic if given more.
This commit is contained in:
Dmitry Chestnykh 2014-08-09 17:03:38 +02:00
parent 7dd3037eec
commit b09047d1ee
2 changed files with 23 additions and 3 deletions

View File

@ -48,14 +48,18 @@ func NewLen(length int) string {
func NewLenChars(length int, chars []byte) string { func NewLenChars(length int, chars []byte) string {
b := make([]byte, length) b := make([]byte, length)
r := make([]byte, length+(length/4)) // storage for random bytes. r := make([]byte, length+(length/4)) // storage for random bytes.
clen := byte(len(chars)) clen := len(chars)
maxrb := byte(256 - (256 % len(chars))) if clen > 256 {
panic("uniuri: maximum length of charset for NewLenChars is 256")
}
maxrb := 256 - (256 % len(chars))
i := 0 i := 0
for { for {
if _, err := io.ReadFull(rand.Reader, r); err != nil { if _, err := io.ReadFull(rand.Reader, r); err != nil {
panic("error reading from random source: " + err.Error()) panic("error reading from random source: " + err.Error())
} }
for _, c := range r { for _, byte := range r {
c := int(byte)
if c > maxrb { if c > maxrb {
// Skip this number to avoid modulo bias. // Skip this number to avoid modulo bias.
continue continue

View File

@ -50,4 +50,20 @@ func TestNewLenChars(t *testing.T) {
} }
// Check that only allowed characters are present // Check that only allowed characters are present
validateChars(t, u, chars) 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)
} }