Menu

#338 std::random_device not working properly

v1.0 (example)
pending-invalid
niXman
None
5
2019-04-02
2013-05-06
Anonymous
No

A simple demonstration of the std::random_device

#include <random>
#include <iostream>

int main(){
std::random_device rd;
std::cout<<rd();
return 0;
}

Compiling with MinGW w64, every execution of the program gives the same output, while with MSVC (and according to C++ standard), the output is different each time.

Discussion

  • niXman

    niXman - 2013-10-09

    Which version is used?

     
  • niXman

    niXman - 2014-09-17
    • assigned_to: niXman
    • Group: --> v1.0 (example)
     
  • Kai Tietz

    Kai Tietz - 2014-09-17

    That is red hearing. The rand-function uses pseudo-random-value calculation. Depending to the version of the used msvcrt, MS changed to random-value gathering via internal advapi32 function (of course unnamed and undocumented).
    So you will see that not even just for each process those numbers are the same (for same seed), even for each thread within the same process those numbers are repeating.
    This is nothing specific to mingw-w64, as we don't implement that function. We are using function provided by msvcrt.dll.

     
  • Kai Tietz

    Kai Tietz - 2014-09-17
    • status: open --> pending-invalid
     
  • niXman

    niXman - 2014-09-17

    I have implementation using CryptoAPI, but for gcc-4.6. Sometime I will fix it for gcc-trunk and commit to GCC...

     

    Last edit: niXman 2014-09-17
    • Sergey Zubkov

      Sergey Zubkov - 2017-02-09

      any news on that CryptoAPI implementation?

       
  • Kai Tietz

    Kai Tietz - 2017-02-20

    Hmm, I think gcc 4.6 won't be fixed here. In general this isn't a bug from our POV. The implementation of rand() in msvcrt is a bit poor, and so you should use for more modern implementations rand_s() instead.
    I would suggest you to provide a private implementation of rand(), which uses rand_s internally, and link it with your project. This sould solve your issue.
    Otherwise I am tempted to close this bug as won't fix.

     
    • Sergey Zubkov

      Sergey Zubkov - 2017-02-20

      This isn't about rand at all, this is about std::random_device.

       
  • Kai Tietz

    Kai Tietz - 2017-02-20

    it is about rand(). There is no "random device" on Windows. So libstdc++ tries to use here for c++11 a file /dev/urandom, or the file /dev/random. A closer look to its implementation on windows should reveal that easily. As libstdc++ is nothing maintained by mingw-w64 directly, this issue is better to be reported upstream to libstdc++ people.

     
  • Henric Jungheim

    Henric Jungheim - 2018-02-10

    For reference, the API call in question is RtlGenRandom. Despite what the API page says, Microsoft is unlikely to remove or otherwise disable the call since that would break applications compiled by MSVC++ since 2005 or so that depend, directly or indirectly, on rand_s() and other major apps like Firefox and Chrome that use RtlGenRandom directly. That just isn't going to happen.

    If libstdc++ is still broken then given how many apps use random_device to seed the mt19937 generator (just look at all the examples in books, on StackOverflow, etc), this renders MinGW or any other g++ cross compiler that relies on the broken libstdc++ behavior for Windows dangerous to use. "The behavior is consistent with the standard," can both be true and irrelevant. People are relying on random_device to provide seed material at least as good as time(NULL).

    This shows an example of how to use RtlGenRandom:
    Cryptographically Secure Random number on Windows without using CryptoAPI

    Purists can that are running Win7 and later can use BCryptGenRandom instead.

     
  • Olly Betts

    Olly Betts - 2019-04-02

    Someone's reported this issue in to the libstdc++ people, and it looks like there's a patch in progress: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85494

     

Log in to post a comment.