If the rand()
function creates a random number that is 4 bytes in length, and I wanted to create a random number that is 1024 bits in length (128 bytes), is the easiest method to get this by concatenating the rand()
function 256 times or is there an alternative method?
#include <stdio.h>
#include <string.h>
int main(void) {
const char data[128];
memset(&data, 0x36, 128);
printf("%s\n", data);
puts("");
printf("%d\n", sizeof(data)/sizeof(data[0]));
puts("");
int i = 0;
unsigned long rez = 0;
for(i = 0; i < 20; i++) {
unsigned int num = rand();
rez = rez + num;
printf("%x\n", rez);
}
printf("%x\n", rez);
return 0;
}
is the easiest method to get this by concatenating the rand() function 256 times or is there an alternative method?
Each rand()
returns a value in the [0...RAND_MAX]
range. RAND_MAX
is limited to 32767 <= RAND_MAX <= INT_MAX
.
Very commonly RAND_MAX
is a Mersenne number of the form 2n − 1. Code can take advantage of this this very common implementation dependent value. Each rand()
call then provides RAND_MAX_BITS
and not 32 as suggested by OP for a 4-byte int
. @Matteo Italia
[See far below update]
#include <stdlib.h>
#if RAND_MAX == 0x7FFF
#define RAND_MAX_BITS 15
#elif RAND_MAX == 0x7FFFFFFF
#define RAND_MAX_BITS 31
#else
#error TBD code
#endif
Call rand()
⌈size * 8 / RAND_MAX_BITS⌉
times. This eases the number of rand()
calls needed from size
.
void rand_byte(uint8_t *dest, size_t size) {
int r_queue = 0;
int r_bit_count = 0;
for (size_t i = 0; i < size; i++) {
int r = 0;
//printf("%3zu %2d %8x\n", i, r_bit_count, r_queue);
if (r_bit_count < 8) {
int need = 8 - r_bit_count;
r = r_queue << need;
r_queue = rand();
r ^= r_queue; // OK to flip bits already saved in `r`
r_queue >>= need;
r_bit_count = RAND_MAX_BITS - need;
} else {
r = r_queue;
r_queue >>= 8;
r_bit_count -= 8;
}
dest[i] = r;
}
}
int main(void) {
uint8_t buf[128];
rand_byte(buf, sizeof buf);
...
return 0;
}
If you want the easiest bit less efficient code, simply call rand()
for each byte as answered by @dbush
[Update 2021]
@Anonymous Question Guy posted a nifty macro that returns the bit width of a Mersenne number, more generally than the #if RAND_MAX == 0x7FFF
approach above.
/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \
+ (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))
_Static_assert((RAND_MAX & 1 && (RAND_MAX/2 + 1) & (RAND_MAX/2)) == 0,
"RAND_MAX is not a Mersenne number");
#define RAND_MAX_BITS IMAX_BITS(RAND_MAX)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With