#1260 Seeding the random number generator

yachris Sat 23 Oct 2010

Hello,

I'm sorry if I missed this somewhere, but I've tried googling all kinds of phrases and I can't figure out how to seed the random number generator. As it says in the javadoc for Java's Random class, "If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers." Very useful (nigh indispensable!) for some kinds of testing.

Thanks!

brian Sat 23 Oct 2010

Since the random functions are just static methods, under the covers they just use a java.security.SecureRandom instance to provide the strongest strength (in the JVM at least)

yachris Sat 23 Oct 2010

SecureRandom does provide a setSeed(long) instance method... any way we could get access to it?

EDIT: NEVER MIND: SecureRandom.setSeed(long) is just there to provide compatibility with java.util.Random. It doesn't work, alas... Guess I'll write my own class.

DanielFath Tue 26 Oct 2010

Yachris if you make this a RNG please post a link, I (and I thing others as well) really need a P-RNG for testing as well.

rosarinjroy Tue 26 Oct 2010

Yachris: You cannot use SecureRandom to produce a sequence of pseudo random numbers as the SecureRandom adds the seed you have provided over and above the seed it already has. Could you please share with us what was the problem you faced when you attempted to use the java.util.Random with seed?

yachris Tue 26 Oct 2010

Hi rosairnjroy,

Could you please share with us what was the problem you faced when you attempted to use the java.util.Random with seed?

Well, one of us is misunderstanding the other :-). I didn't have a problem with using java.util.Random (other than speed of my implementation, of which more soon). I did have a problem trying to use the setSeed(long) method on java.security.SecureRandom, however. It's documented in its javadoc as just providing backward compatibility with java.util.Random, but it has no effect on the sequence of pseudo-random numbers generated.

yachris Tue 26 Oct 2010

Hello,

I've put up my Seedable random number generator classes on GitHub:

http://github.com/yachris/SRandom-for-Fantom

Enjoy.

rosarinjroy Wed 27 Oct 2010

Hi yachris: I guess I didn't understand your question. Thank you for sharing the code.

DanielFath Thu 28 Oct 2010

Thanks yachris, I really hope Fantom includes this handy util in next revision.

katox Wed 24 Nov 2010

Unavailability of seeded pseudo random generator in the core is quite painful. I'd suggest adding a variant method srandom(Int seed) (or seeding Env.cur and then using srandom with no parameters) to Float, Range and List.

The alternative is to provide a distribution classes like in R or C++ boost. But I think it is an overkill to have those in core.

DanielFath Wed 24 Nov 2010

I think a math pod with its own Imaginary, Random and Matrix classes would be in order. Hell I could probably whip up something like that in my free time.

brian Fri 26 Nov 2010

I don't think during my entire career I have ever wanted to explicitly seed the random generator, especially when you just want the system to pick a really good seed.

Can you explain why this is needed? Is this a testing issue?

DanielFath Fri 26 Nov 2010

Two things. Testing and (book) examples.

When writing books it is good to have seed so your examples behave consistently when run.

katox Fri 26 Nov 2010

Another usage, though a bit unusual, is that you set up a common seed for a number of systems. Then if you have the same pseudo-random generating system everywhere you can synchronize them using this sequence. The advantage is you don't have to use timestamps and that the sequence numbers are not easily predictable (unless you make the seed public).

brian Sun 28 Nov 2010

Okay, it sounds like there is a need for a seeded random generator in the core library. Here are options:

  1. create new class in sys, downside is that it clutters up sys with what I consider a non-core class
  2. create new class in util, downside is that I was hoping to keep util free of natives
  3. add an opaque handle to Int.random function which could be used to create instances of seeded generators, downside is not a very intuitive API

katox Sun 28 Nov 2010

There is also an option suggested by @DanielFath which I think makes a lot of sense

  1. create a math pod and put more advanced stuff in there. It could naturally grow over time - complex math, matrices, probability function, distribution functions, statistics, as needed...

Sidenote: I consider all functionality that needs natives as "core" because if you can't write it in pure Fantom you're in trouble.

On the other hand I would like the core to be written in Fantom whenever possible to avoid portability issues due to large native parts (like Java SE). It doesn't mean there couldn't be more implementations of a single API (generic Fantom and more performant native implementations for specific target platforms).

brian Mon 29 Nov 2010

Any other votes for a new math pod?

Henri Mon 29 Nov 2010

+1 for math pod

jodastephen Mon 29 Nov 2010

Always tricky, but a new pod may be a good idea.

That said, a Fraction/Ratio class could be argued to have a literal, pushing it to core:

Ratio r := 2|3

(two thirds)

On the side point, I would like to see most of sys written in Fantom. It makes it easier to follow that way.

brian Mon 29 Nov 2010

On the side point, I would like to see most of sys written in Fantom. It makes it easier to follow that way.

Ideally yes this would be nice. However it was a bootstrap issue and everything had to originally be written in Java. Now at this point the question is does it make sense to start rewriting things in Fantom? Might be nice, but I don't think it would provide a lot of value given how much effort it would take, especially compared to all the other things we could work on. Although I definitely think at some point that would be really nice.

Any more votes for math versus other homes/solutions for a Random class?

DanielFath Tue 30 Nov 2010

+1, I guess. I'm already working on it. In fact I already made a native Random class in Fantom using MerseneTwister so it should be really fast. As soon as I complete nextInt(Range r) I'll post the repo location.

BTW is sys::Int.shiftl the equivalent of << in Java?

katox Tue 30 Nov 2010

BTW is sys::Int.shiftl the equivalent of << in Java?

It is eq. of <<. shiftr is however eq. of >>> for practical reasons.

brian Tue 30 Nov 2010

Promoted to ticket #1260 and assigned to brian

I will create a Random class in the standard library.

Right now the leading suggestion is to put it into a new math pod which might be a collection for other math classes.

DanielFath Tue 30 Nov 2010

Ok Mersenne twister is done. I don't guarantee that it behaves as it should (uniform distribution) so an opinion of an expert would be welcome.

I'd like to see some comparisons but so far Mersenne was rather fast. It chugged about N = 1 000 000 iterations per test in only 25347ms.

brian Tue 30 Nov 2010

That is cool since it is 100% Fantom (in which case it might be nice to stick in util). However, I'm sort of thinking we really need to stick to Java's SecureRandom to ensure that we have really good randomization for security algorithms.

That would be another option - maybe Random belongs in a crypto pod - I think I prefer that to math. Plus crypto would all be wrappers around the Java classes which would make sense to natives.

yachris Tue 30 Nov 2010

I'm sort of thinking we really need to stick to Java's SecureRandom to ensure that we have really good randomization for security algorithms.

Would it be possible to have a crypto.Random that uses SecureRandom under the hood for security algorithms, and (say) util.Random that is seedable? I discovered that SecureRandom is not seedable (which is kind of where this discussion started :-)

rfeldman Tue 30 Nov 2010

+1 to separate crypto.Random and util.Random (or math.Random or whatever) methods.

DanielFath Tue 30 Nov 2010

Thanks. I pretty much copy/pasted the original Java implementation. The algorithm I used is rather fast, but not very safe (It says so in its doc). It's best suited for simulations (Monte Carlo, etc.) and absolutely not for any crypto related purpose.

So +1 to seperate crypto.Random and math.Random. The two use cases are rather different. Former preffers high entropy over speed, while second can floss over lower entropy if it has lots of speed.

One question though. Is there a .Net version of SecureRandom?

brian Tue 30 Nov 2010

I discovered that SecureRandom is not seedable (which is kind of where this discussion started

SecureRandom has a constructor which takes the seed as a byte[]. So I don't see a problem doing a crypto::Random class that allows the seed to be specified.

msl Tue 30 Nov 2010

SecureRandom has a constructor which takes the seed as a byte[]. So I don't see a problem doing a crypto::Random class that allows the seed to be specified.

The problem is that the seed isn't the only thing SecureRandom uses to generate it's numbers - it also incorporates entropy from external sources on each call (hence its performance degradation vs Random in trade off for its security gains).

For example:

import java.security.SecureRandom;
public class SecureRandomTest {
    public static void main(final String[] args) {
        for (int i = 0; i < 10; i++) {
            SecureRandom sr = new SecureRandom("this is a test of the secure random's seed".getBytes());
            System.out.println(sr.nextInt());
        }
    }
}

Outputs:

133454951
56775745
1052098215
134735290
-612061948
567376491
286393058
-337029297
626043875
-166346806

brian Tue 30 Nov 2010

I think the best way to handle it might be just make a mode in crypto::Random that uses normal util.Random under the covers.

katox Tue 30 Nov 2010

I think normal java.util.Random backed (seeded) implementation is just fine for most but crypto purposes or statistics which is sensitive to random distribution functions.

SecureRandom is also _much_ slower though I wouldn't see it as a big problem. Repeatability is.

math and crypto pod can have their own definitions (or even multiple) I don't see a problem there.

brian Tue 30 Nov 2010

I am not planning on adding two implementations to the core distro right now. I think one is enough. Since there will definitely be a crypto pod soon, I think that is the right place for it. And I can make crypto::Random do double duty as repeatable non-secure and also as secure.

DanielFath Mon 3 Jan 2011

If you ever require pure Fantom implementation of Random. My Mersenne twister has been checked against java version of it and the first 1000 seeds match. Must say I hate a.xor(b) syntax though.

brian Mon 3 Jan 2011

Ticket resolved in 1.0.57

I decided to go ahead and put the class in util since that is sort of its expected location. It uses Java's implementations under the covers. The API is:

abstract class Random
{
  static Random makeSecure()
  static Random makeSeeded(Int seed := DateTime.nowTicks)

  abstract Int next(Range? r := null)
  abstract Bool nextBool()
  abstract Float nextFloat()
  abstract Buf nextBuf(Int size)
}

Login or Signup to reply.