Populate a region of memory with random data
RAND_MAX
is guaranteed to be at least 215−1 so there is no problem filling an entire byte with randomness with a single call to rand()
, unless your architecture has bytes larger than 15 bits (in which case your hard-coded multiplication by 8 will also be problematic).
Doing the generation byte by byte is straight-forward and requires no bit-hacking cleverness.
Personally, I wouldn't worry about "wasting bits" from a call to rand()
; the bits produced by that standard library function aren't worth much on most implementations. The real problem is to decide which bits to throw away so that the remaining ones are reasonably well-distributed. If possible, to cope with the range of inferior PRNGs generally used, you should go for the middle bits.
A better solution might be to simply provide your own PRNG; portable source code implementations exist, and some are well studied.
fill memory with random data
Linux provides you with /proc/pid/maps
and /proc/pid/mem
, for your own pleasure. Of course you have to be extra careful when writing there. Also, keep in mind the only memory segment available to each process is its own, so you'll probably have to do some attaching and code patching to get where you want. Good luck, anyways. :)
edit: It's still quite a few times more complicated than a code audit - which also has greater chances to reveal the actual source of the problem.
Filling memory with random bytes - C/Objective-C
You can use arc4random_buf
to fill the buffer with random data:
#include <stdlib.h>
#include <stdint.h>
uint8_t iv[kCCBlockSizeAES128];
arc4random_buf(&iv, kCCBlockSizeAES128);
Also, the memory block returned by malloc
(as with any uninitialised memory) is filled with garbage. You should not assume that it will be filled with anything, especially not cryptographically useful random numbers.
Create buffer and fill it with random numbers
You need
malloc (size*sizeof(int))
instead of
malloc (size*sizeof(uint8_t))
or maybe you need
uint8_t* buffer = malloc (size*sizeof(uint8_t));
It depends if you want a buffer of 10 int
of a buffer of 10 uint8_t
.
For printing the content of the buffer use:
for (i = 0; i < size; i++)
{
printf("%d\n", buffer[i]) ;
}
Following line only prints the address of the buffer.
printf("Content of buffer = %d\n", buffer);
Filling an array with random numbers in a range in C
Georgi.
I've made a successfull test with the following code.
I think the problem could be a several things, but mainly allocating memory locally instead globally.
If this won't help you, I suggest you put here the complete code for your attempt application.
:)
void randomgen(int *intarray, int size, int max, int min)
{
int i;
for (i = 0; i < size; i++) {
intarray[i] = (rand() % (max - min + 1)) + min;
printf("%d ", intarray[i]);
}
}
int main(int argc, char **argv){
int *iA;
int i;
if ( (iA = (int*)malloc(20 * sizeof(int))) == NULL ){
printf("error");
return 0;
}
randomgen(iA, 20, 59, 50);
for (i = 0; i < 20; i++) {
printf("iA[%d]=%d\n", i, iA[i]);
}
return 0;
}
It produces the following output:
53 56 57 55 53 55 56 52 59 51 52 57 50 59 53 56 50 56 52 56
iA[0]=53
iA[1]=56
iA[2]=57
iA[3]=55
iA[4]=53
iA[5]=55
iA[6]=56
iA[7]=52
iA[8]=59
iA[9]=51
iA[10]=52
iA[11]=57
iA[12]=50
iA[13]=59
iA[14]=53
iA[15]=56
iA[16]=50
iA[17]=56
iA[18]=52
iA[19]=56
Fill huge file with random data quickly
Your limiting factor is probably the speed of your hard disk. Nevertheless you may gain some performance by splitting the work in two. One thread (the producer) will produce the random lines, and another thread (the consumer) will write the produced lines in the file. The code bellow writes 1,000,000 random lines to a file in my SSD in less than a second (10 MB).
BlockingCollection<string> buffer = new(boundedCapacity: 10);
Task producer = Task.Factory.StartNew(() =>
{
Random random = new();
StringBuilder sb = new();
for (int i = 0; i < 10000; i++) // 10,000 chunks
{
sb.Clear();
for (int j = 0; j < 100; j++) // 100 lines each chunk
{
sb.AppendLine(random.Next().ToString());
}
buffer.Add(sb.ToString());
}
buffer.CompleteAdding();
}, default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
Task consumer = Task.Factory.StartNew(() =>
{
using StreamWriter outputFile = new(@".\..\..\Huge.txt");
foreach (string chunk in buffer.GetConsumingEnumerable())
{
outputFile.Write(chunk);
}
}, default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
Task.WaitAll(producer, consumer);
This way you don't even need thread safety in the production of the random lines, because the production happens on a single thread.
Update: In case the writing to disk is not the bottleneck, and the producer is slower than the consumer, more producers can be added. Below is a version with three producers and one consumer.
BlockingCollection<string> buffer = new(boundedCapacity: 10);
Task[] producers = Enumerable.Range(0, 3)
.Select(n => Task.Factory.StartNew(() =>
{
Random random = new(n); // Non-random seed, same data on every run
StringBuilder sb = new();
for (int i = 0; i < 10000; i++)
{
sb.Clear();
for (int j = 0; j < 100; j++)
{
sb.AppendLine(random.Next().ToString());
}
buffer.Add(sb.ToString());
}
}, default, TaskCreationOptions.LongRunning, TaskScheduler.Default))
.ToArray();
Task allProducers = Task.WhenAll(producers).ContinueWith(_ =>
{
buffer.CompleteAdding();
}, TaskScheduler.Default);
// Consumer the same as previously (omitted)
Task.WaitAll(allProducers, consumer);
How to initialize a struct with random data in C?
Okay, I actually found the answer to my own question. The main problem is that there isn't an initializer for my struct. However, there already exist serialization functions. So we can use the non-working second solution, and convert it to a working solution.
So a much cleaner solution would be:
myStruct testData = {0};
myStruct readData = {0};
uint8_t* randomData = genRandomData(sizeof(myStruct));
memcpy(&testData, randomData, sizeof(myStruct));
save(&testData);
load(&readData); // readData is now a valid random struct.
myStruct realReadData = {0}
save(&readData);
load(&realReadData);
memcmp(readReadData, readData, sizeof(myStruct)); // This does equal 0 if serialize/deserialize functions are correct.
If there's an issue in serialize/deserialize functions, the input struct (corrupt as it may be) should provide different results.
Related Topics
Automate Scp with Multiple Files with Expect Script
Change a String in a File with Sed
How Does The 64 Bit Linux Kernel Kick Off a 32 Bit Process from an Elf
Chmod a Freshly Mounted External Drive to Set Up Writing Access
Print Stdout/Stderr and Write Them to a File in Bash
Different Utf-8 Signature for Same Diacritics (Umlauts) - 2 Binary Ways to Write Umlauts
Launching Linux from Busybox (Pivot_Root or Switch_Root, or ? )
How to Pass Local Variable to Remote Using Ssh and Bash Script
Convert Charset from a Entire Project to Utf-8
Remove a List of Words from Filename
Path Issue After Compiling Curl
Installing Ffmpeg on Amazon Linux - Cpp, Gcc & Libstdc++ Dependancies
Why Does Wget Output to Stderr Rather Than Stdout
Bash: Getting Percentage from a Frequency Table
What's The Meaning of 'C' in Result of Command "Ls -L /Dev/Tty'