Generating distinct random numbers from uint256 in range

302 Views Asked by At

My goal is to generate around 1500 distinct random numbers, from range 8000.

I receive (blockchain ChainLink VRF - connected to random oracle, but that's not important):

  • variable array of uint256[] randomValues: unsigned values <0, 2^256-1>
  • i convert this field right away to numbers from my range, using ( randomValues[i] MOD 8000 ) + 1.
  • Since I want to create distinct numbers, I guess I should be calling generating function until I have enough of them.

My question is if you know about more efficient way how to generate array of distinct random numbers from array of numbers like [ 106182753482634914995248705155707514089551099076291415270692202660364749508656, 45628802998066180854454684078101263717187335597784096973096012883499998820379, .. ]?

1

There are 1 best solutions below

7
On BEST ANSWER

Ok, this is more practical than theoretical, but maybe someone will find it useful. I decided to go another way on this one (using python3 random module).

  1. I shuffle generated list of numbers 1..10000 using Mersenne twister (MT)
  2. python3 random.shuffle() is using Fisher-Yates shuffle; as a randomness initiator for random I am using large integer, I use it to seed MT
  3. for 1500 list items MT needs seed of size = log2(1500!) bits, note that for python3 seed longer than 20.000 bits is cut
  4. after shuffle, first 1500 list items are kept
  5. I have 1500 items from range

As @r.e.s. mentioned in comments, MT has 219937−1 possible states, that's why single run has to be held under 2080 items - to be able to reach every random permutation.

Also random.sample() seems to be an option.