I don’t believe I’ll ever absorb all the wondrous potential of Linux/Unix. Case in point is the /dev/random
file. It’s exactly what the name implies: random stuff. And you can use this nifty file in your C programs to generate random values.
Available in Linux, Unix, and macOS (sorry, Windows), the /dev/random
file is classified as a special character file type. Its purpose is to generate random values. If you use the cat command to “view” it, you see garbage puke all over the terminal window; press Ctrl+C to halt the spew. (The random output can inadvertently mess with some terminal settings, so be careful.)
According to the all-knowing Wikipedia, the file uses “noise” from various device drivers to generate its random values. That’s good enough for me, and a reliable way on a *NIX box to obtain a random value, as shown in this code:
2022_10_22-Lesson-a.c
#include <stdio.h> int main() { const char filename[] = "/dev/random"; FILE *dr; int c; dr = fopen(filename,"r"); if( dr ) { c = fgetc(dr); printf("Random value: %d\n",c); fclose(dr); } return(0); }
The /dev/random
file is declared as a string constant at Line 5. It’s a character file, so I use the stream oriented fopen() function at Line 9 to open it for reading. Upon success, the if statements execute, fetching a single character (int variable c
) from the file and outputting it at Line 13. The file is closed at Line 14. Note that you don’t need to seed a randomizer to employ this technique.
Here is the output:
Random value: 169
This update to the code reads ten values from the file:
2022_10_22-Lesson-b.c
#include <stdio.h> int main() { const char filename[] = "/dev/random"; const int size = 10; FILE *dr; int c,x; dr = fopen(filename,"r"); if( dr ) { for( x=0; x<size; x++ ) { c = fgetc(dr); printf("Random value: %d\n",c); } fclose(dr); } return(0); }
Constant int value size
sets the number of integers to output. A for loop is added to fetch and output the ten values:
Random value: 131
Random value: 105
Random value: 172
Random value: 54
Random value: 158
Random value: 185
Random value: 201
Random value: 110
Random value: 73
Random value: 67
To gobble all ten values into an array, I updated the code to use the fread() function to consume the array in a single gulp:
2022_10_22-Lesson-c.c
#include <stdio.h> int main() { const char filename[] = "/dev/random"; const int size = 10; FILE *dr; int r[size]; int x; dr = fopen(filename,"r"); if( dr ) { fread(&r,sizeof(int),size,dr); for( x=0; x<size; x++ ) { printf("Random value: %d\n",r[x]); } fclose(dr); } return(0); }
Array r[]
is declared at Line 8. The fread() function at Line 14 grabs the ten integers at once, setting them into the array. A for loop outputs the values; the output is similar to the preceding example.
To read larger values, again I use the fread() function to procure an unsigned long integer value from the /dev/random
file:
2022_10_22-Lesson-d.c
#include <stdio.h> int main() { const char filename[] = "/dev/random"; FILE *dr; unsigned long r; dr = fopen(filename,"r"); if( dr ) { fread(&r,sizeof(unsigned long),1,dr); printf("Random value: %lu\n",r); fclose(dr); } return(0); }
The fread() function at Line 12 specifies the size of an unsigned long value, reading the value from open file dr
and setting into variable r
. Here is sample output:
Random value: 15304796159533619025
You can read real numbers as well. This code update consumes a double value from the /dev/random
file:
2022_10_22-Lesson-e.c
#include <stdio.h> int main() { const char filename[] = "/dev/random"; FILE *dr; double r; dr = fopen(filename,"r"); if( dr ) { fread(&r,sizeof(double),1,dr); printf("Random value: %f\n",r); fclose(dr); } return(0); }
The output here is interestingly whacky:
Random value: -3581507666920258283702881838842193028636242448207
7114148082694520146327147739765556024935895227752040177045026700
73182756975969049482863570233961353096133083136.000000
Do consider using this approach when your code needs a quick-and-dirty yet random value. This trick is yet another nifty thing about Linux and similar operating systems.