0

I have maximum number of bits that is not bit aligned E.g. 35 and required to generate unique random number from 1 - 68719476734 (max number for 35 bits). Could use SecureRandom but will have to extract 5 bytes out of it and convert to Long maybe, but chances of collision seem to a concern. What are some options to generate a random for this range. Could i seed this random with nanoTime maybe if there is a collision and regenerate in this range.

user964287
  • 713
  • 1
  • 7
  • 11
  • 1
    What do you mean by "chances of collision seem to a concern"? For true random values, there is always a chance of collision, and there is nothing you should do about that. If you remove the chance of collision, the result will not be truly random. – Andreas Mar 12 '21 at 01:41
  • Seeking a seed which is random enough to avoid collisions from just any randon – user964287 Mar 12 '21 at 01:45
  • 1
    Why do you believe that nanoTime will cause better randomness than whatever algorithm is built into the `SecureRandom` class? – Andreas Mar 12 '21 at 01:46
  • That's where I am seeking a seed if it can be used for SecureRandom. How to ensure a range with SecureRandom without a seed in that case – user964287 Mar 12 '21 at 01:51

2 Answers2

1

First, a few comments:

  • The max value for 35 bits is 34359738367, not 68719476734.
    68719476734 is not even the max value for 36 bits, 68719476735 is.

  • Do not seed a SecureRandom. That reduces the security of it.

To generate a 35-bit random number, excluding value zero, just generate a long random value, take the last 35 bits, and redo if the value is zero.

SecureRandom r = new SecureRandom();

long value;
do {
    value = r.nextLong() & ((1L << 35) - 1);
} while (value == 0);
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

There may be a better way, but perhaps this can help. The first simply prints the single number generated from a stream. The second masks off the required bits. Interesting that the values for the same seed are different (which I can't explain). But the first method which allows a range might be sufficient for what you want. I am clearly not an expert on this but provided it to foster some ideas.

SecureRandom r = new SecureRandom();
 r.setSeed(23);
// generate a sum of 1 element to get the element from the stream.
long v = 0;
while (v == 0) {
   v = r.longs(1,1L<<34, (1L<<35)-1).sum();
}
System.out.println(v);
System.out.println(64-Long.numberOfLeadingZeros(v));

r.setSeed(23);
long vv = 0;
while (vv == 0) {
   vv = r.nextLong()&((1L<<35)-1);
}

System.out.println(vv);
System.out.println(64-Long.numberOfLeadingZeros(vv));

prints

31237208166
35
9741674490
34

My assumption here was that the stream version above would not be provided if the random numbers did not meet the secure requirements.

WJS
  • 36,363
  • 4
  • 24
  • 39