-1
int main(){

    uint8_t *wdata = NULL;
    wdata = calloc(5, sizeof(uint8_t));

    for (int j =0;j<5;j++){

        wdata[j] = rand();

    }

}

The rand() function generates 16 bits of data. How do I generate 8 bits of random values? Do I need to use a custom function for the same?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ShivaniSarin
  • 17
  • 3
  • 6
  • 1
    So rand returns 16bits, just use 8 of it and discard the rest. – KamilCuk Nov 19 '18 at 16:10
  • 3
    What you've got will assign the least significant 8 bits of the 16-bit value that you say is returned by `rand()`. Many versions of `rand()` will return 32-bit values, but that's a separate discussion. The only problem with using the least significant 8 bits is that they may not be as random as you'd like — they might fail various tests of randomness. How much that matters depends on what you're going to do next. Most likely, you can simply use the code shown. Failing that, you probably need a better pseudo-random number generator (PRNG) than `rand()`. – Jonathan Leffler Nov 19 '18 at 16:10
  • In exactly what way did this cause a problem? Did you just assume that your code is not working? – klutt Nov 19 '18 at 16:13
  • 1
    @JonathanLeffler If you discard some of the random value by a power of 2, it'll still be an even distribution of randomness, won't it? e.g. `rand() % 16`, `rand() % 32`, `rand() % 64`, etc. – Fiddling Bits Nov 19 '18 at 16:19
  • 1
    See https://stackoverflow.com/questions/11418113/lack-of-randomness-in-c-rand and especially links from it, such as to the paper by Marsaglia (sp?). – Jonathan Leffler Nov 19 '18 at 16:48
  • 3
    @fiddling: if rand is implemented with a.linear congruential generator, then the period of rand%2**i is 2**i, which is not very random for small `i`. – rici Nov 19 '18 at 18:32

2 Answers2

4

How to generate an 8 bit random number in C

Given code such as

uint8_t *wdata = calloc( 5, sizeof( uint8_t ) );

something like

for ( int j = 0;j < 5; j++ )
{
    wdata[ j ] = rand();
}

will work fine.

Integer assignment to an unsigned value truncates, which is exactly what you want. See 6.5.16.1 Simple assignment of the C Standard.

Note that RAND_MAX is guaranteed by 7.22.2 Pseudo-random sequence generation functions, paragraph 5 to be at least 32767, which is "wider" than 8 bits, so the result is guaranteed to "fill up" an 8-bit variable.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Yes, but, http://c-faq.com/lib/notveryrand.html. See http://c-faq.com/lib/randrange.html. – Neil Nov 19 '18 at 19:58
  • 1
    @NeilEdelman A poor PRNG is a poor PRNG, and when the modulo value is much less than the maximum result from the PRNG the modulo operation itself won't add any measurable bias to the result. – Andrew Henle Nov 20 '18 at 17:38
0

Because 8 bit number can contain maximum 0-255. so if i divide rand()%256 we get 8 bit random number.

  int main(){
    uint8_t *wdata = NULL;
    wdata = calloc(5, sizeof(uint8_t));
    for (int j =0;j<5;j++){
        wdata[j] = rand()%256;
   }
}

for more randomness you use some prime number add or subtract difference after dividing from 256.

Neuron
  • 5,141
  • 5
  • 38
  • 59
  • 1
    Since they are unsigned 8 bit numbers, `rand()%256` and `rand()` produce the same thing; although, it may be some benefit for readability. – Neil Nov 19 '18 at 19:14
  • rand(void) returns a pseudo-random number in the range of 0 to RAND_MAX. RAND_MAX is a constant whose default value may vary between implementations but it is granted to be at least 32767. – Susheel Dwivedi Nov 19 '18 at 19:24