Hi everyone and good morning :) .
i want to simply read from the linux file "urandom" a random number and print it out on screen.just simple as that.
this function should be in a file called myrandom.c ( myrandom.h must be made also, which has my function dekleration ) . i will have to compile it later to a static libray and to dynamic library, and then write a main program which prints out 5 random numbers using the static library .
and another main program which prints out 5 random numbers using the dynamic library.
i wrote the myrandom.c code and myrandom.h code i dont know if they are correct .
i tested myrandom.c inside a main program and it gives me random number , but its very big .
ist that the right way to grap a random number from the urandom file?
many thanks

#include <myrandom.h>

int myRandom(){

int rNumber = fopen("/dev/urandom","r");

printf("this is a random number from the file urandom : %d", &rNumber);

return rNumber;



// the header file ( myrandom.h ) :

int myRandom();

Recommended Answers

All 10 Replies

You need to #include <stdio.h> to get the declaration of fopen. As it is now you're implicitly declaring fopen in a way that is incompatible with its definition. You should be getting a warning about that (and in C99 and later you should instead be getting an error that you're using a function without a declaration).

Once you do that, you should be getting another warning that you're implicitly converting the result of fopen from FILE* to int. That's because fopen doesn't read anything from the file nor does it return an int. fopen opens the file and then returns a file pointer. That file pointer can then be given to other file IO functions (like fread, fwrite, fgets, fscanf, fprintf etc.), which will actually read from or write to the file. Once you're done working with the file, you need to close it by passing the file pointer to fclose.

So no, you're not currently doing it correctly. The number you're printing is simply the numeric value of whichever pointer was returned by fopen. It has nothing to do with the contents of the file.

You're also using printf incorrectly. When you are printing out the value of an int, printf does not want the address of that int. It wants the int itself.

printf("%d", &rNumber); is wrong.
printf("%d", rNumber); is right.

commented: Ah, I missed that. Another thing that any decent compiler warns about. +8

thanks for the replies .
i dont know how the content of the urandom file is structured , i want to read a random number from it .
it doesnot work still , but this is my code now hope you help me .

#include <stdio.h>

int main(void){

    int str[1];

FILE *fpointer;


fpointer = fopen("/dev/urandom", "r");

fgets(str,1,fpointer);

printf("the random number is : %d\n", *(&str) );


//fseek(fpointer, (int)random()*10,SEEK_SET);


//fread(fpointer);

fclose(fpointer);

     return 0;
}

Before I get to my answers, let me ask you a question: what is your purpose in accessing dev/urandom? Is this for a class assignment, or part of a larger project? Is there a specific reason why the usual srand()/rand() functions aren't sufficient? What are your goals in doing this?

OK, now that that is out of the way, here goes. The first thing to know is that /dev/urandom (and the files in the /dev directory in general) isn't actually a file at all; it is a pseudo-device, a sort of handle for accessing the kernel pseudo-random number generator in this case.

To read either /dev/random or /dev/urandom, you need to read in a block of one or more bytes (type char is usually used, though using uint8_t might make it more easily understood that the buffer is being used for it's numeric value), which you would then pack into the integer either by using shifts, or by having the buffer as a union of two overlapping buffers:

#define INT_BUF 32 
#define BYTE_BUF (sizeof(int) * INT_BUF);

union 
{
    uint8_t buffer[BYTE_BUF];
    int rand_values[INT_BUF];
} random_buffer;

This StackOverflow thread explains how to read from /dev/urandom effectively, including why you might want to read several values at once. Note that in one of the later answers, it is explained that you ought to check to make sure that dev/urandom hasn't been spoofed to /dev/zero or something similar before reading from it.

The difference between dev/random and /dev/urandom is that random blocks when it runs out of entropy, while urandom does not. Now, the 'non-blocking' part about urandom is important, because of how the system generates enough entropy to get a reasonable approximation of randomness. The kernel PRNG uses hardware noise from various devices (mainly the hard disk(s)) to re-seed the PNRG periodically, to increase the randomness. However, it has to collect that information over time, if too many random values are drawn from it, it can run out of this accumulated data. When that happens, then /dev/random will block - it will wait until there is enough entropy collected to re-seed the PRNG. However, /dev/urandom will instead continue using the existing seed, which means that eventually, it will come back to it's starting point and begin repeating it's previous output. Thus while /dev/urandom is easier to work with consistently, it does not ensure randomness to the degree that /dev/random does. I would further add that while both are meant to provide cryptographically secure randomness, both have known weaknesses; if you have a hardware RNG in your system (which should be accessible through dev/hwrng if there is one), using that would be preferable.

hi , thanks for the fast help , yes its an class assignment and sadly no one is helping not even the class lecture mentions anything about it , the say go google it. so we are lost. we are total beginners to operating systems, we had only Java introduction class.

WTF is going on with this?

 int str[1];
 printf("the random number is : %d\n", *(&str) );

It's still wrong. str is effectively an int*, so &str is an int**, so *(&str) is an int*. So you're doing exactly what you were doing before (wrongly providing an int* when you should be providing an int) but by a crazy roundabout route.

ok , im still working on it sorry but im new to C .
this is the code i wrote.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define NUM 100000


int main(void){

int str[NUM];
int i = 0;
FILE *fpointer;

/* changing the constant value of the time which will be multiplicated to produce the random number , this way we get diffrent values each time we run the program.*/

srand(time(NULL));  

/* for reading non text files. b for binary*/

fpointer = fopen("/dev/urandom", "rb"); 

/* reading 100000 elements each is 8 Bytes (64bit Ubuntu)*/

for (i=0;i<NUM;i++){      

 /* each loop read from the file stream fpointer 1 item which is 8 Bytes in size (64bit Ubuntu) and store it in the array str */

 fread(str+i,sizeof(int),1,fpointer);  

}

/* generates a random number between 0 and 99999 */

int rNumber = (int)rand()%NUM; 

/* prints out a random number stored inside the str array*/

printf("this is my random number : %d\n",str[rNumber] ); 



fclose(fpointer);

     return 0;
}

That does seem a bit better, although it's still a bit odd.

Given that your aim is "to simply read from the linux file 'urandom' a random number and print it out on screen" why do you read NUM times, and then output a random one of those? Why not just read one from urandom, and print that?

#include <stdio.h>

int main(void)
{
  int randomvalue;
  FILE *fpointer;
  fpointer = fopen("/dev/urandom", "rb");
  fread(&randomvalue,sizeof(int),1,fpointer);  
  fclose(fpointer);
  printf("this is my random number : %d\n",randomvalue); 
  return 0;
}

yes thats way more easier , thank you :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.