1bf4844c67599735c972cc6287d49b4e6b0a99b9
[cmccabe-bin] / pickrand.go
1 package main
2
3 import (
4         "bytes"
5         "crypto/rand"
6         "fmt"
7         "math/big"
8         "os"
9         "path/filepath"
10 )
11
12 func main() {
13         root := "."
14         if len(os.Args) > 1 {
15                 root = os.Args[1]
16         }
17         files := make([]string, 0, 32)
18         err := filepath.Walk(root, func(p string, f os.FileInfo, err error) error {
19                 if err != nil {
20                         return err
21                 }
22                 if !f.IsDir() {
23                         files = append(files, p)
24                 }
25                 return nil
26         })
27         if err != nil {
28                 fmt.Fprintf(os.Stderr, "** Error: %s\n", err.Error())
29                 os.Exit(1)
30         }
31         var b [8]byte
32         _, err = rand.Read(b[:])
33         if err != nil {
34                 fmt.Fprintf(os.Stderr, "Failed to access cryptographic randomness.  " +
35                         "Error: %s\n\n", err.Error())
36                 os.Exit(1)
37         }
38         i, err := rand.Int(bytes.NewReader(b[:]), big.NewInt(int64(len(files))))
39         if err != nil {
40                 fmt.Fprintf(os.Stderr, "Failed to get a random int.  Error: %s\n", err.Error())
41                 os.Exit(1)
42         }
43         j := int(i.Uint64())
44
45         fmt.Printf("%s\n", root + "/" + files[j])
46 }