0
int random_ticket;
get_random_bytes(&random_ticket, sizeof(random_ticket));

I tried to do it like this but I think this method gives random numbers between 0 and infinity. I am not so sure about how to get random numbers between 1 and 7.

Can you please explain how can I do it?

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • 2
    'this method gives random numbers between 0 and infinity' umm...that is not possible in a finite universe. – Martin James Apr 29 '22 at 09:57
  • 1
    The answer to [this question](https://stackoverflow.com/questions/40961482/how-to-use-get-random-bytes-in-linux-kernel-module) suggests `random_ticket = 1 + (random_ticket % 7)` but use `unsigned` not `int`. – Weather Vane Apr 29 '22 at 10:01

1 Answers1

1

Use unsigned math to reduce the range to [1...7]

%, the remainder operator is like a mod operator when used in unsigned math. Useful to reduce the range to 7 different values. A slight bias is introduced though as the typical 232 number of different values of an unsigned is not a multiple of 7.

unsigned random_ticket;

// () not needed with sizeof object
get_random_bytes(&random_ticket, sizeof random_ticket); 

// Best to use unsigned constants with unsigned objects.
random_ticket = 1u + (random_ticket % 7u); 

Do not use a signed int and random_ticket = 1 + (random_ticket % 7); as random_ticket % 7 returns values in the [-6 ... 6] range.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Bump. Also, why burn an entire `unsigned` worth of random on a value that only requires a single octet (in fact, a single nibble if you really want to crack down, but then it just becomes tedious). – WhozCraig Apr 29 '22 at 11:15
  • 1
    @WhozCraig One argument for a longer string of bits being reduced would be that it reduces the effect of bias. – Thomas Jager Apr 29 '22 at 11:19
  • @WhozCraig Fair point. Since 7 is not a factor of a byte width or nibble, using an "entire `unsigned` worth of random" reduces the biased introduced with the simple `% 7u`. True that code could use narrower types (and perhaps additional code to cope with bias), yet an assumption here is also that 7 is illustrative to demo the issue. – chux - Reinstate Monica Apr 29 '22 at 11:20
  • Hmmm, I wonder if even possible to get a fair distribution of 7 if one wanted a constant time solution. – chux - Reinstate Monica Apr 29 '22 at 11:26
  • @chux-ReinstateMonica: Suppose there is a constant time solution that requires at most some fixed number n of samples. n samples of 2^32 bits has 2^(32n) possible states. Each state must map to one of the seven results, and there can be no reject-and-retry outcomes, since at most n samples may be used. 2^(32n) is not divisible by seven. Therefore this is not possible. – Eric Postpischil Apr 29 '22 at 12:35
  • @EricPostpischil Since applying `get_random_bytes(pointer, byte_size)` to form 7 different values in constant time is not doable (per [comment](https://stackoverflow.com/questions/72056137/how-can-i-get-random-numbers-between-1-7-in-kernel-using-get-random-bytes/72056770?noredirect=1#comment127322065_72056770)), then a `get_random_constant_time(pointer, range)` is needed. – chux - Reinstate Monica Apr 29 '22 at 16:01