title: How to succinctly, portably, and thoroughly seed the mt19937 PRNG?
body: <p>I seem to see many answers in which someone suggests using <code>&lt;random&gt;</code> to generate random numbers, usually along with code like this:</p>
  
  <pre><code>std::random_device rd;  
  std::mt19937 gen(rd());
  std::uniform_int_distribution&lt;&gt; dis(0, 5);
  dis(gen);
  </code></pre>
  
  <p>Usually this replaces some kind of "unholy abomination" such as:</p>
  
  <pre><code>srand(time(NULL));
  rand()%6;
  </code></pre>
  
  <p>We might <a href="https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful" rel="noreferrer">criticize</a> the old way by arguing that <code>time(NULL)</code> provides low entropy, <code>time(NULL)</code> is predictable, and the end result is non-uniform.</p>
  
  <p>But all of that is true of the new way: it just has a shinier veneer. </p>
  
  <ul>
  <li><p><code>rd()</code> returns a single <code>unsigned int</code>. This has at least 16 bits and probably 32. That's not enough to seed MT's 19937 bits of state.</p></li>
  <li><p>Using <code>std::mt19937 gen(rd());gen()</code> (seeding with 32 bits and looking at the first output) doesn't give a good output distribution. 7 and 13 can never be the first output. Two seeds produce 0. Twelve seeds produce 1226181350. (<a href="http://www.pcg-random.org/posts/cpp-seeding-surprises.html" rel="noreferrer">Link</a>)</p></li>
  <li><p><code>std::random_device</code> can be, and sometimes is, implemented as a simple PRNG with a fixed seed. It might therefore produce the same sequence on every run. (<a href="https://stackoverflow.com/questions/18880654/why-do-i-get-the-same-sequence-for-every-run-with-stdrandom-device-with-mingw">Link</a>) This is even worse than <code>time(NULL)</code>.</p></li>
  </ul>
  
  <p>Worse yet, it is very easy to copy and paste the foregoing code snippets, despite the problems they contain. Some solutions to the this require acquiring <a href="http://www.pcg-random.org/" rel="noreferrer">largish</a> <a href="http://www.boost.org/doc/libs/1_64_0/doc/html/boost_random.html" rel="noreferrer">libraries</a> which may not be suitable to everyone.</p>
  
  <p>In light of this, my question is <strong>How can one succinctly, portably, and thoroughly seed the mt19937 PRNG in C++?</strong></p>
  
  <p>Given the issues above, a good answer:</p>
  
  <ul>
  <li>Must fully seed the mt19937/mt19937_64.</li>
  <li>Cannot rely solely on <code>std::random_device</code> or <code>time(NULL)</code> as a source of entropy.</li>
  <li>Should not rely on Boost or other libaries.</li>
  <li>Should fit in a small number of lines such that it would look nice copy-pasted into an answer.</li>
  </ul>
  
  <p><strong>Thoughts</strong></p>
  
  <ul>
  <li><p>My current thought is that outputs from <code>std::random_device</code> can be mashed up (perhaps via XOR) with <code>time(NULL)</code>, values derived from <a href="https://en.wikipedia.org/wiki/Address_space_layout_randomization" rel="noreferrer">address space randomization</a>, and a hard-coded constant (which could be set during distribution) to get a best-effort shot at entropy.</p></li>
  <li><p><code>std::random_device::entropy()</code> <a href="https://stackoverflow.com/questions/28390843/how-to-find-the-true-entropy-of-stdrandom-device">does not</a> give a good indication of what <code>std::random_device</code> might or might not do.</p></li>
  </ul>