web-dev-qa-db-ja.com

mingw gcc4.8.1でstd :: random_deviceを実行するたびに同じシーケンスを取得するのはなぜですか?

_c++ <random>_ライブラリをテストするには、次のコードを使用します。

コンパイルされた実行可能ファイルの実行ごとにまったく同じシーケンスを取得するのはなぜですか? rd()はコンパイル時に決定的ですか?実行ごとに異なる出力を取得するにはどうすればよいですか?

Windows 7 64ビット上のGCC 4.8.1。 http://nuwen.net/mingw.html からMinGWディストリビューションを使用する

EDIT:Visual Studioで同じコードをテストしました。問題はない。出力は非決定的です。これは、私が使用したmingw gcc 4.8.1のバグである可能性があります。

_#include <iostream>
#include <random>
using namespace std;
int main(){
 random_device rd;
 mt19937 mt(rd());
 uniform_int_distribution<int> dist(0,99);
 for (int i = 0; i< 16; ++i){
    cout<<dist(mt)<<" ";
 }
 cout <<endl;
}
_
66
ahala

から http://en.cppreference.com/w/cpp/numeric/random/random_device

非決定的ソース(ハードウェアデバイスなど)が実装に利用できない場合、std :: random_deviceは擬似乱数エンジンの観点から実装されることに注意してください。

ただし、少なくともRNGをシードするための適切な実装が期待されます。

編集:ストリームが約束されたほどランダムではないという事実を明らかにするために、彼らは毎回同じシーケンスを配信することを意図的に選んだと思います。

32
Mark Ransom

MSFTからのSTL :から確認済みの回答を得ました。

VCとは異なり、GCCはWindowsにrandom_deviceを非決定的に実装していません。 Boostは持っているので、Boost.Randomを使用できます。

24
ahala

コンストラクターにパラメーターを渡す必要がある場合があります。

https://gcc.gnu.org/onlinedocs/gcc-4.9.1/libstdc++/api/a00899.html

3
user877329
  1. GCCはrd.entropy()を正しく実装していません-常に0を返します(少なくともMac OS Xでは)。

  2. 残念ながら、追加のエントロピーをrandom_deviceに混合する方法はないようです。これは通常/しばしば(Linuxの/ dev/randomと/ dev/urandomを見て、Intel RDRANDの実装を見て)疑似乱数ジェネレーターを実装しているためです。フードの下。エントロピーソースが生成するものと混合するためにランダムと見なすものを注入することにより、出力を改善できるようにしたいと思います。繰り返しますが、このデバイス(またはカーネルモジュール)内部で暗号化アルゴリズムを実装取得したエントロピービットを処理して出力を生成するため、インジェクションによってそのプロセスをさらに「ランダム化」できるようにしたいと思います。そのデバイスが選択するエントロピーと混合するための自分のデータ。たとえば、Java SecureRandom()を検討してください。これは、setを許可しません(実際に変換されます)それをPRNGに変換します)、しかし、それはあなたが提供するものとそれが使用するものと喜んで混合して、その出力をさらに「ランダム化」するでしょう。

  3. 個人的にはRDRANDが好きです。コンパクトなCインターフェイスを備えた小さなアセンブリライブラリ。参考文献は次のとおりです。

    StackoverflowのRDRANDについてはIntelのDavid Johnsonが説明しています

    Windows、Linux、およびMac OS XのRDRANDライブラリソースへのStackoverflowポインター

    RDRANDライブラリに関するIntelブログ、およびダウンロードリンク

2
Mouse