Generate n random bytes based on m-byte seed in Java

1.4k views Asked by At

I'd like to generate n random bytes from a given m-byte seed. The generated sequence has to be reproducible; for the same seed the same sequence has to be generated. n can be either higher or lower than m.

The two following trivial approaches that are coming to my mind are biased:

  • Hash the m bytes to create a long seed to feed a new java.util.Random generator. Problem: I discard entropy if n<8, as the default Random seed in Java is a 8-byte long.
  • Hash the m bytes to generate some "random" data. Problem: this cap n to some value (20 for SHA1 for example).

Is there a standard way of doing this? I did not see any relevant class in java.security, but I guess this is a basic need for cryptography?

Note: I do not need "crypto-level extra-secure" random, just random that passes basic statistical randomness tests. Also I'd prefer relying on standard code instead of having to code everything by myself.

Edit: java.security.SecureRandom(byte[] seed) does not fit the bill, the generated sequence is purely random and does not depend only on the seed (at least on my JVM, but I'd like to have a predictable result).

1

There are 1 answers

0
Laurent Grégoire On BEST ANSWER

For the record, a (rather slow) solution as discussed above:

    public byte[] rand(byte[] seed, int n) {
        try {
            byte[] data = null;
            ByteArrayOutputStream ret = new ByteArrayOutputStream(n);
            while (ret.size() < n) {
                MessageDigest md = MessageDigest.getInstance("SHA1");
                md.update(seed);
                if (data != null)
                    md.update(data);
                data = md.digest();
                ret.write(data, 0, Math.min(n - ret.size(), data.length));
            }
            return ret.toByteArray();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

This generates 1M "random" bytes in ~500ms, and passes very basic statistical randomness tests. Maybe picking a faster hash than SHA1 would speed-up the thing, did not investigated that.