23

I have this big char array that needs to filled with random bytes in high freq. I wonder if there is any faster way other than the naive way (using for loop - fill each cell with random byte) to do this. There is no requirement on the random quality of the values. Any "random" junk will do. Platform is windows

Nordic Mainframe
  • 28,058
  • 10
  • 66
  • 83
GabiMe
  • 18,105
  • 28
  • 76
  • 113
  • 2
    For what is this used, because with that info it's very hard to give a proper solution. – orlp Sep 15 '11 at 08:20
  • Just need to simulate a un initialized memory area with junk in it – GabiMe Sep 15 '11 at 08:22
  • 8
    http://xkcd.com/221/ just `memset` an arbitrary value. – amit Sep 15 '11 at 08:23
  • @nightcracker: I disagree, he wants an efficient way to fill a char buffer with random values without having to iterate through each byte in the array. It's pretty clear to me, at least. – brain Sep 15 '11 at 08:23
  • 1
    If there's no requirement on the random quality, `memset(ptr, 0, len)` will fill the buffer up with a [random number](http://xkcd.com/221/) just fine. – Jon Sep 15 '11 at 08:23
  • 5
    http://www.cpunk.de/images/randomness.png – wormsparty Sep 15 '11 at 08:45
  • try `gcry_randomize` from the `gcrypt` library: https://gnupg.org/documentation/manuals/gcrypt/Retrieving-random-numbers.html – Sparkler Aug 31 '20 at 11:22

8 Answers8

23

True random (Unix only):

int fd = open("/dev/random", O_RDONLY);
read(fd, your_buffer, buffer_size);

Not completely random (Unix only):

int fd = open("/dev/urandom", O_RDONLY);
read(fd, your_buffer, buffer_size);

Constant random (unless you use srand(time(NULL)), portable):

for(size_t i = 0; i < buffer_size; i++)
    your_buffer[i] = rand() % 256;

Or something like:

memcpy(your_buffer, (void*)memcpy, buffer_size);
wormsparty
  • 2,481
  • 19
  • 31
  • `memcpy(your_buffer, (void*)memcpy, buffer_size);` may fail for big buffers. Also `% 256` is redundant – ST3 Nov 07 '13 at 08:04
5

Depends if you're on Linux or Windows but on Linux doing a memcpy from /dev/random should work.

On Windows you can use CryptGenRandom to fill a buffer with random data: http://msdn.microsoft.com/en-us/library/aa379942.aspx. Apparently this is the Windows equivalent of reading data out of /dev/random. Python uses it to implement its OS.urandom function on Windows: http://en.wikipedia.org/wiki/CryptGenRandom

sashang
  • 11,704
  • 6
  • 44
  • 58
1

A very fast and simple way of generating a large array of uniformly distributed random numbers is to use the Mersenne twister. If speed is critical, this could even be done using SIMD.

Don Reba
  • 13,814
  • 3
  • 48
  • 61
1

You could probably do something like, if your buffer size can be divided by 4.

unsigned int v = rand(), *ptr = (unsigned int *)buf;
for(int i = 0; i < buffer_size / 4; i++)
    ptr[i] = (v << 16) ^ rand();

Just an idea ;)

brain
  • 2,507
  • 1
  • 13
  • 12
0

I have written a library that produces "almost random" buffers: using multiple buffers filled with pseudo-random random data, the library randomly pick a buffer and returns it to the application.

This library was designed first to be as fast as possible given memory consumption is cheap and bandwidth high.

It can be used for block based processing: the data produced is not really random, but the way the buffers are presented to the application is, so it generates a random stream which can be large enough to defeat some compression algorithm.

You can find it at: https://gitorious.org/randbuf/

Yann Droneaud
  • 5,277
  • 1
  • 23
  • 39
  • Is there any benefit from picking from multiple buffers, or is that just for novelty and memory wastage ;) ? – Isaac Woods Aug 11 '15 at 17:14
  • @IsaacWoods because otherwise the same data will be written in the user's buffers endlessly. By using multiple source buffers, choosen at random, it makes the data stream less predictable. – Yann Droneaud Nov 09 '15 at 14:10
0

Set up a buffer with junk values ahead. If you need to fill the char array with random bytes again, then just memcpy parts from the junk-buffer at random offsets to the char array until it is completely overwritten. memcpy is usually very fast and optimized to take advantage of SIMD and cache instructions. If you are copying segments large enough, then the overhead of selecting the random offsets if negligible - you are generating junk data with the speed of memcpy.

Nordic Mainframe
  • 28,058
  • 10
  • 66
  • 83
0

Since this question is labeled windows/winapi you could use CryptGenRandom.

CommonSense
  • 341
  • 1
  • 6
-2

This seems to do what you need:

srandom(42);
memset(ptr, random(), len);

Only a single random number is generated but the data will be "random" enough to let you spot a lot of errors based on uninitialized memory. You can change the seed and rerun the program to test with different data.

If you need this for debugging you might also want to take a look at Valgrind.

Jørgen Fogh
  • 7,516
  • 2
  • 36
  • 46