Reproducible Random Values in Vector of Arbitrary Length

97 views Asked by At

I need to generate a random number corresponding to each value in an index, where it needs to be reproducible for each index value, regardless of how many indexes are given:

As an example, I might provide the indexes 1 to 10, and then in a different time, call the indexes for 5 to 10, and they both need to be the same for the values 5 to 10. Setting a global seed will not do this, it will only keep same for the nth item in the random call by position in the vector.

What I have so far is this, which works as desired:

f = function(ix,min=0,max=1,seed=1){
  sapply(ix,function(x){
    set.seed(seed + x)
    runif(1,min,max)
  })
}
identical(f(1:10)[5:10],f(5:10)) #TRUE
identical(f(1:5),f(5:1)) #FALSE
identical(f(1:5),rev(f(5:1))) #TRUE

I was wondering if there is a more efficient way of achieving the above, without setting the seed explicitly for each index, as an offset to global seed.

2

There are 2 answers

4
rossum On

Use an encryption. With a given key, unique inputs will always produce unique outputs. As long as the numbers you input are distinct then the outputs will always be different; the same numbers will always encrypt to the came output cyphertext. Use DES for 64 bit numbers or AES for 128 bit numbers. For other sizes either roll your own Feistel cipher (insecure, but random) or use Hasty Pudding cipher.

0
Ralf Stubner On

You can use the digest package for tasks like this:

library(digest)
f = function(ix, seed=1){
  sapply(ix, digest, algo = "sha256", seed = seed)
}
identical(f(1:10)[5:10],f(5:10)) #TRUE
#> [1] TRUE
identical(f(1:5),f(5:1)) #FALSE
#> [1] FALSE
identical(f(1:5),rev(f(5:1))) #TRUE
#> [1] TRUE