-1

I am C++ student and I am working on creating a random number generator.

Infact I should say my algorithm selects a number within a defined range.

I am writing this just because of my curiosity.

I am not challenging existing library functions.

I always use library functions when writing applications based on randomness but I am again stating that I just want to make it because of my curiosity.

I would also like to know if there is something wrong with my algorithm or with my approach. Because i googled how PRNGs work and on some sites they said that a mathematical algorithm is there and a predefined series of numbers and a seed just sets the pointer in a different point in the series and after some intervals the sequence repeats itself.

My algorithm just starts moving to and fro in the array of possible values and the seed breaks the loop with different values each time. I don't i this approach is wrong. I got answers suggesting a different algorithm but they didn't explain What's wrong with my current algorithm?

Yes,there was a problem with my seed as it was not precise and made results little predictable as here:-

cout< < rn(50,100);

The results in running four times are 74,93,56,79.

See the pattern of "increasing order".

And for large ranges patterns could be seen easily.I got an answer on getting good seeds but that too recommended a new algorithm(but didn't say why?).

An alternative way could be to shuffle my array randomly generating a new sequence every time.And the pattern of increasing order will go off.Any help with that rearranging too will also be good.Here is the code below.And if my function is not possible please notify me.

Thanking you in anticipation.

int rn(int lowerlt, int upperlt)
{
    /* Over short ranges, results are satisfactory.
     * I want to make it effective for big ranges.
     */

    const int size = upperlt - lowerlt; // Constant size of the integer array.

    int ar[size]; // Array to store all possible values within defined range.
    int i, x, ret; // Variables to control loops and return value.
    long pointer = 0; //pointer variable. The one which breaks the main loop.


    // Loop to initialize the array with possible values..
    for (i=0, x=lowerlt; x <= upperlt; i++, x++)
        ar[i]=x;

    long seed = time(0);

    //Main loop . To find the random number.
    for (i=0; pointer <= seed; i++, pointer++)
    {
        ret = ar[i];
        if (i == size-1)
        {
            // Reverse loop.
            for (; i >= 0; i--)
            {
                ret=ar[i];
            }
        }
    }

    return ret;
}
anjanik012
  • 149
  • 3
  • 11
  • 3
    The 'main problem' is that writing RNGs is hard, and there is nothing in particular to recommend the approach you've taken. An answer to this question would only consist of suggesting another, existing algorithm, which you could equally as well find for yourself, with more benefit. – user207421 Jan 30 '16 at 05:32
  • @EJP Building RNGs is hard or not, finding solutions are important. I know of library functions. I am just asking for little help. I am just curious to know of different programming techniques. I am new here. – anjanik012 Jan 30 '16 at 05:50
  • So go find one, as I recommended. Rather than starting with guesswork. You'll learn a lot. – user207421 Jan 30 '16 at 05:55
  • @EJP Yeah i will find one. That's why i came here. – anjanik012 Jan 30 '16 at 05:58
  • 2
    **PRNG are a very difficult subject**, if you want to write one which is competitive w.r.t. existing implementations. So either use an existing one (from ``) or *spend years to study them*. Or **edit your question** to explain why you are writing one. – Basile Starynkevitch Jan 30 '16 at 08:19

2 Answers2

0

Caveat: From your post, aside from your random generator algorithm, one of your problems is getting a good seed value, so I'll address that part of it.

You could use /dev/random to get a seed value. That would be a great place to start [and would be sufficient on its own], but might be considered "cheating" from some perspective.

So, here are some other sources of "entropy":

Use a higher resolution time of day clock source: gettimeofday or clock_gettime(CLOCK_REALTIME,...) call it "cur_time". Use only the microsecond or nanosecond portion respectively, call it "cur_nano". Note that cur_nano is usually pretty random all by itself.

Do a getpid(2). This has a few unpredictable bits because between invocations other programs are starting and we don't know how many.

Create a new temp file and get the file's inode number [then delete it]. This varies slowly over time. It may be the same on each invocation [or not]

Get the high resolution value for the system's time of day clock when the system was booted, call it "sysboot".

Get the high resolution value for the start time of your "session": When your program's parent shell was started, call it "shell_start".

If you were using Linux, you could compute a checksum of /proc/interrupts as that's always changing. For other systems, get some hash of the number of interrupts of various types [should be available from some type of syscall].

Now, create some hash of all of the above (e.g.):

dev_random * cur_nano * (cur_time - sysboot) * (cur_time - shell_start) *
getpid * inode_number * interrupt_count

That's a simple equation. You could enhance it with some XOR and/or sum operations. Experiment until you get one that works for you.

Note: This only gives you the seed value for your PRNG. You'll have to create your PRNG from something else (e.g. earl's linear algorithm)

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
0
unsigned int Random::next() {
    s = (1664525 * s + 1013904223);
    return s;
}

's' is growing with every call of that function. Correct is

unsigned int Random::next() {
   s = (1664525 * s + 1013904223) % xxxxxx;
   return s;
}

Maybe use this function

long long Factor = 279470273LL, Divisor = 4294967291LL;
long long seed;
next()
{
    seed = (seed * Factor) % Divisor;
}
Georg Fuss
  • 315
  • 2
  • 9