Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a string as input to the rand.Seed() function in Golang?

What I want to do:

Based on the contents of a string (like a1b2c3d4e5, for example), I want to generate a bunch of "repeatable" random events. Generating repeatable random numbers in Golang is easy - you just seed the random number generator with a specific number using the rand.Seed() function, and then you are done.

However, the rand.Seed() function takes an int64 as an argument. So I will need to convert a string to a int64 somehow.

What I tried already:

My first thought was to encode the string using base64, and then convert the sequence of bytes to a int64. However, through some basic testing that only seems to support strings of around 7 length. After I add an 8th character, the number just stays the same.

I guess the fundamental problem here is that there are more possible string values than there are possible int64 values.

So what about some kind of hash function? Most hash functions that I know of return a sequence of bytes; I would need some kind of hash function that returns an int64. Perhaps this approach is also misguided?

like image 794
James Avatar asked Dec 18 '22 01:12

James


1 Answers

A hash of the string will do the trick.

You can use:

  • md5 sum of the string (returns 16 bytes)
  • convert the first 8 bytes into a uint64 (binary.BigEndian.Uint64 ignores the rest. It will crash if your input is less than 8 bytes though).

Sample code (playground link):

package main

import (
    "crypto/md5"
    "encoding/binary"
    "fmt"
    "io"
    "math/rand"
)

func main() {
    h := md5.New()
    io.WriteString(h, "And Leon's getting larger!")
    var seed uint64 = binary.BigEndian.Uint64(h.Sum(nil))
    fmt.Println(seed)
    rand.Seed(int64(seed))
    fmt.Println(rand.Int())
}

Prints:

2458341265858962012
792667671

Note: md5 is just an example. You can use any hash that generates at least 8 bytes. eg: sha256. Simply replace md5.New() with sha256.New() (and the import). You can find a nice list of hash examples here.

And a big word of warning: this does not talk about crypto applications at all. I'm assuming this is for something like a user-provided seed (eg: a game seed) for non-crypto purposes.

like image 163
Marc Avatar answered May 07 '23 01:05

Marc