Mersenne Twister random-number generator function Have a look at this Mersenne Twister random-number generator function that I've written based on what I found on SO.

As I am a beginner and don't understand half of the stuff below, I would very much appreciate if you guided me a little on my journey to improving this random number generator.


I don't need it to be fast, I just want it to be secure.
I want it to be more or less the most secure way of generating numbers.
All that, because I plan on generating random passwords with it later on.




#include &lt;iostream&gt;
#include &lt;random&gt;

unsigned long long int random_integer(unsigned long long int rand_min, unsigned long long int rand_max)
{

    // initialize = seed the random device
    std::random_device random_device;

    // use Mersenne Twister as random-number generator engine
    std::mt19937 random_number_generator(random_device());

    // number distribution, guaranteed unbiased 
    std::uniform_int_distribution&lt;int&gt; number_distribution(rand_min, rand_max);

    return number_distribution(random_number_generator);

}

int main()
{

    for (int i = 1; i &lt;= 10; i++)
    {
        std::cout &lt;&lt; random_integer(1, 1000) &lt;&lt; std::endl;
    }

    return 0;

}


Notes:


I'm on Linux.
Compiler is g++5.
Standard being C++17.
Math

Well, I believe usually you could avoid the math, but this is a special case. The main things to cover is random variable, random functions and distributions. It is gonna help a lot. Do note that int distribution is discrete, whereas real distribution is continuous.

Code Review


Incorrect usage of twister

First of all, std::mt19937 generates only 32 bit random numbers. This means that by truncating it to int (not always, depends on the platform), the code will discard higher (or lower) 16 bits of the number.

The twister has state, which means that when function generates one random number, it will discard the state and start from scratch when called again. Although std::random_device might normalize the behavior, the output will not be as intended.
Incorrect usage of distribution

std::uniform_distribution has a constructor taking T min, T max, which means that unsigned long long will overflow the arguments, which I believe is undefined behavior.

Return type is unsigned long long, but generates values are of type int, which means that higher (or lower) bits will be zero or garbage. Both of the cases are wrong. 


Different solution

If you want a generator without all of the hoops to jump through, just slam everything into a class. Here is the rough sketch (might not compile):

#include &lt;random&gt;

class uniform_int_generator
{
    std::mt19937_64 twister;
public:
    uniform_int_generator():
                  twister(std::random_device{}())
    {}

    unsigned long long operator()(unsigned long long max_val, unsigned long long min_val)
    {
        std::uniform_int_distribution&lt;unsigned long long&gt; distr(max_val, min_val);
        return distr(twister);       
    }
};


You might want to add some customization points using templates. Anyway, if you need more, make this one compile and post question with the updated code.