簡體   English   中英

為什么每次使用 std::random_device 和 mingw gcc4.8.1 運行時都會得到相同的序列?

[英]Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?

我使用以下代碼來測試 C++ <random>庫。

為什么每次運行編譯的可執行文件時我都會得到完全相同的序列? rd()在編譯時是確定性的嗎? 如何為每次運行獲得不同的輸出?

Windows 7 64 位上的 GCC 4.8.1。 使用來自http://nuwen.net/mingw.html 的MinGW 分發。

編輯:我用 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;
}

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

請注意,如果非確定性源(例如硬件設備)對實現不可用,則 std::random_device 可以根據偽隨機數引擎實現。

不過,我希望有一個不錯的實現,至少可以為 RNG 播種。

編輯:我懷疑他們每次都故意選擇提供相同的序列,以表明流並不像承諾的那樣隨機。

從 MSFT 的 STL得到了確認的答案:

與 VC 不同,GCC 沒有在 Windows 上非確定性地實現 random_device。 Boost 有,所以你可以使用 Boost.Random。

您可能需要將參數傳遞給構造函數:

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

這是GCC 錯誤,已在 GCC 9.2 中修復。

如果您遇到此問題,請更新您的編譯器。 (例如,您可以從 MSYS2 獲取新的 GCC。)

  1. GCC 沒有正確實現 rd.entropy() - 它總是返回 0(至少在 Mac OS X 上)。

  2. 不幸的是,似乎沒有辦法將額外的熵混合到 random_device 中,這很重要,因為它通常/經常(查看 Linux /dev/random 和 /dev/urandom,以及英特爾 RDRAND 實現)實現了一個偽隨機數生成器在引擎蓋下。 我希望能夠通過注入一些我認為隨機的東西與它的熵源產生的任何東西混合來提高它的輸出。 同樣,由於這個設備(或內核模塊)在內部實現了一種加密算法來處理它獲得的熵位以生成其輸出,我希望能夠通過注入我自己的數據與任何東西混合來“隨機化”這個過程設備選擇的熵。 例如,考慮 Java SecureRandom()。 它不允許您設置種子(這確實會將其轉換為 PRNG),但它會很樂意將您提供的內容與它用來“隨機化”其輸出的任何內容混合在一起。

  3. 我個人更喜歡 RDRAND。 具有緊湊 C 接口的小型匯編庫。 以下是參考資料:

    英特爾的 David Johnson 在 Stackoverflow 上解釋了 RDRAND

    Stackoverflow 指向適用於 Windows、Linux 和 Mac OS X 的 RDRAND 庫源代碼

    英特爾關於 RDRAND 庫的博客和下載鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM