Securely shuffling an array with 75 numbers in Go I have a SHA512 hex string consisting of my random input and that of the user.

Since rand.Seed only accepts a int64 I can never generate enough possibilities to shuffle an array with numbers 1-75: 75! = 2.480914e+109.

So my plan was to loop over the hex string 11 times, each time converting 10 hex characters to decimal and keep on shuffling the numbers.

func Shuffle(t []int, hex string) {
    for j := 0; j &lt; 11; j++ {
        shuffleSeed, _ := strconv.ParseInt(hex[j*10:(j+1)*10], 16, 64)
        rand.Seed(shuffleSeed)
        for i := 1; i &lt; len(t); i++ {
            r := rand.Intn(i + 1)
            if i != r {
                t[r], t[i] = t[i], t[r]
            }
        }
    }
}

items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
    61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75}

hex := "099b5721eaa9b5bcd87a07366aa175a1fb5b6fa6e5671b93ef443df927474198ec2ae959928f95c46f9fe9621575aa4e1e6f70780b059044da17737fcc99a322"
Shuffle(items, hex)


What do you think about this? I'm not a cryptography expert, not a math expert and certainly not a Go expert (I started yesterday).

Taken from another post I shuffled an array with [1,2,3] and here are the occurrences of each after 1 million times:


167136
166403
166877
166520
166925
166145
Initialization

A simple loop would be easier to maintain than hard-coding an array of 75 values.

items := make([]int, 75, 75)
for i := range items {
    items[i] = i + 1
}


Seeding

The PRNG should be seeded just once.

You are correct that an Int64 seed is "only" capable of producing 264 ≈ 1019 distinct sequences, which is well under 75! ≈ 10109.

However, you should also consider the magnitude of the numbers involved.  The age of the Universe is well under 1018 seconds.  There is therefore no way you could remotely come close to producing a small fraction of the 75! possible permutations, just due to lack of time.  A 64-bit seed is more than enough to generate as many unreproducible sequences as you could ever want.

So, calling rand.Seed(time.Now().UnixNano()) just once in func init() will be sufficient.