package main import ( "bytes" "crypto/rand" "flag" "fmt" "math/big" "os" "path/filepath" "time" ) func main() { flag.Usage = func() { fmt.Fprintf(os.Stdout, "pickrand.go: picks a random file.\n") fmt.Fprintf(os.Stdout, "\n") flag.PrintDefaults() } prevDays := flag.Int("n", 0, "The number of days back to look.") flag.Parse() var maxDuration time.Duration if (*prevDays != 0) { maxDuration = time.Duration(int64(*prevDays) * (24 * 60 * 60 * 1e9)) } root := flag.Arg(0) if (root == "") { root = "." } files := make([]string, 0, 32) err := filepath.Walk(root, func(p string, f os.FileInfo, err error) error { if err != nil { return err } if maxDuration != 0 { var duration = time.Now().Sub(f.ModTime()) if duration > maxDuration { return nil } } if !f.IsDir() { files = append(files, p) } return nil }) if err != nil { fmt.Fprintf(os.Stderr, "** Error: %s\n", err.Error()) os.Exit(1) } if len(files) == 0 { fmt.Fprintf(os.Stderr, "No matching files found.\n") os.Exit(1) } var b [16]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", files[j]) }