forked from sneak/util
RandomHexString returns the requested number of bytes from crypto/rand as lowercase hexadecimal, so callers reaching for a token do not end up using the predictable math/rand instead. Comes with a doc comment and table-driven tests. (closes #13) Model: opus-5
58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package util
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"testing"
|
|
)
|
|
|
|
func TestRandomHexStringLength(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
byteLength int
|
|
expectedLength int
|
|
}{
|
|
{"no bytes at all", 0, 0},
|
|
{"one byte", 1, 2},
|
|
{"eight bytes", 8, 16},
|
|
{"sixteen bytes", 16, 32},
|
|
{"thirty-two bytes", 32, 64},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
got, err := RandomHexString(test.byteLength)
|
|
if err != nil {
|
|
t.Fatalf("did not expect an error, got %v", err)
|
|
}
|
|
if len(got) != test.expectedLength {
|
|
t.Errorf("expected a string of %d characters, got %d (%q)", test.expectedLength, len(got), got)
|
|
}
|
|
if _, err := hex.DecodeString(got); err != nil {
|
|
t.Errorf("expected valid hexadecimal, got %q: %v", got, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRandomHexStringRejectsNegativeLength(t *testing.T) {
|
|
got, err := RandomHexString(-1)
|
|
if err == nil {
|
|
t.Errorf("expected an error for a negative length, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestRandomHexStringDiffersBetweenCalls(t *testing.T) {
|
|
seen := make(map[string]struct{})
|
|
|
|
for i := 0; i < 100; i++ {
|
|
value, err := RandomHexString(16)
|
|
if err != nil {
|
|
t.Fatalf("did not expect an error, got %v", err)
|
|
}
|
|
if _, repeated := seen[value]; repeated {
|
|
t.Fatalf("got the same string twice: %q", value)
|
|
}
|
|
seen[value] = struct{}{}
|
|
}
|
|
}
|