pickrand.go: use cryptographic randomness
authorColin P. Mccabe <colin@cmccabe.xyz>
Sat, 9 May 2020 05:33:34 +0000 (22:33 -0700)
committerColin P. Mccabe <colin@cmccabe.xyz>
Sat, 9 May 2020 05:33:34 +0000 (22:33 -0700)
Use cryptographic randomness to avoid getting the same random file
multiple times in a row due to coarse clock granularity.

pickrand.go

index a21efda..1bf4844 100644 (file)
@@ -1,11 +1,12 @@
 package main
 
 import (
+       "bytes"
+       "crypto/rand"
        "fmt"
+       "math/big"
        "os"
        "path/filepath"
-       "math/rand"
-       "time"
 )
 
 func main() {
@@ -27,7 +28,19 @@ func main() {
                fmt.Fprintf(os.Stderr, "** Error: %s\n", err.Error())
                os.Exit(1)
        }
-       rand.Seed(time.Now().UTC().UnixNano())
-       i := rand.Int31n(int32(len(files)))
-       fmt.Printf("%s\n", root + "/" + files[i])
+       var b [8]byte
+       _, err = rand.Read(b[:])
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Failed to access cryptographic randomness.  " +
+                       "Error: %s\n\n", err.Error())
+               os.Exit(1)
+       }
+       i, err := rand.Int(bytes.NewReader(b[:]), big.NewInt(int64(len(files))))
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Failed to get a random int.  Error: %s\n", err.Error())
+               os.Exit(1)
+       }
+       j := int(i.Uint64())
+
+       fmt.Printf("%s\n", root + "/" + files[j])
 }