Skip to main content
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
deleted 47 characters in body; edited tags
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

To fill you in: Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, but I just did that to get a feel for how small 32 bit really is in these days.)

So I am trying to build a function to properly seed a mt19937. This is what I and came up with this:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints the MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however, I have learned that problems with RNG are often times quite subtle.

So the question is: Provided std::random_device produces good, random data on my system, does the above code give me a correctly seeded std::mt19937?

To fill you in: Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, I just did that to get a feel for how small 32 bit really is in these days.)

So I am trying to build a function to properly seed a mt19937. This is what I came up with:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints the MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however I have learned that problems with RNG are often times quite subtle.

So the question is: Provided std::random_device produces good, random data on my system, does the above code give me a correctly seeded std::mt19937?

Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, but I just did that to get a feel for how small 32 bit really is in these days.)

I am trying to build a function to properly seed a mt19937 and came up with this:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints the MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however, I have learned that problems with RNG are often times quite subtle.

Provided std::random_device produces good, random data on my system, does the code give me a correctly seeded std::mt19937?

Tweeted twitter.com/StackCodeReview/status/660742576547487744
added 2 characters in body
Source Link
Baum mit Augen
  • 823
  • 1
  • 7
  • 14

To fill you in: Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, I just did that to get a feel for how small 32 bit really is in these days.)

So I am trying to build a function to properly seed a mt19937. This is what I came up with:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints athe MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however I have learned that problems with RNG are often times quite subtle.

So the question is: Provided std::random_device produces good, random data on my system, does the above code give me a correctly seeded std::mt19937?

To fill you in: Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, I just did that to get a feel for how small 32 bit really is in these days.)

So I am trying to build a function to properly seed a mt19937. This is what I came up with:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints a MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however I have learned that problems with RNG are often times quite subtle.

So the question is: Provided std::random_device produces good, random data on my system, does the above code give me a correctly seeded std::mt19937?

To fill you in: Many people seed their Mersenne Twister engines like this:

std::mt19937 rng(std::random_device{}());

However, this only provides a single unsigned int, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, I just did that to get a feel for how small 32 bit really is in these days.)

So I am trying to build a function to properly seed a mt19937. This is what I came up with:

#include <algorithm>
#include <iostream>
#include <random>

auto RandomlySeededMersenneTwister () {
    // Magic number 624: The number of unsigned ints the MT uses as state
    std::vector<unsigned int> random_data(624);
    std::random_device source;
    std::generate(begin(random_data), end(random_data), [&](){return source();});
    std::seed_seq seeds(begin(random_data), end(random_data));
    std::mt19937 seededEngine (seeds);
    return seededEngine;
}


int main() {
    auto rng = RandomlySeededMersenneTwister();
    for (int i = 0; i < 10; ++i)
        std::cout << rng() << "\n";    
}

This does look like a safe solution to me; however I have learned that problems with RNG are often times quite subtle.

So the question is: Provided std::random_device produces good, random data on my system, does the above code give me a correctly seeded std::mt19937?

Source Link
Baum mit Augen
  • 823
  • 1
  • 7
  • 14
Loading