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?
A hash of the string will do the trick.
You can use:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With