Ich benutze den folgenden Code, um die C ++ - <random>
Bibliothek zu testen .
Warum erhalte ich für jeden Lauf der kompilierten ausführbaren Datei genau die gleiche Reihenfolge? Ist rd()
bei der Zusammenstellung deterministisch? Wie erhalte ich für jeden Lauf eine andere Ausgabe?
GCC 4.8.1 unter Windows 7 64bit. Verwenden der MinGW-Distribution von http://nuwen.net/mingw.html .
BEARBEITEN: Ich habe den gleichen Stückcode mit Visual Studio getestet. Es gibt kein Problem. Die Ausgaben sind nicht deterministisch. Dies könnte ein Fehler in mingw gcc 4.8.1 sein, den ich verwendet habe.
#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;
}
entropy() == 0
. Wenn ja, ist das ein Fehler.random_device
funktioniert das nicht ._GLIBCXX_USE_RANDOM_TR1
bitte dazu bringen, den Inhalt des Makros zu drucken ? Wenn es 0 ist, wird mt19937 mit einem festen Startwert als Fallback verwendet.Antworten:
Von http://en.cppreference.com/w/cpp/numeric/random/random_device :
Ich würde allerdings erwarten, dass eine anständige Implementierung zumindest das RNG auslöst.
Bearbeiten: Ich vermute, sie haben sich bewusst dafür entschieden, jedes Mal dieselbe Sequenz zu liefern, um die Tatsache zu verdeutlichen, dass der Stream nicht so zufällig war, wie versprochen.
quelle
Ich habe eine bestätigte Antwort von STL von MSFT erhalten :
Im Gegensatz zu VC hat GCC random_device unter Windows nicht unbestimmt implementiert. Boost hat, so dass Sie Boost.Random verwenden können.
quelle
Möglicherweise müssen Sie einen Parameter an den Konstruktor übergeben:
https://gcc.gnu.org/onlinedocs/gcc-4.9.1/libstdc++/api/a00899.html
quelle
Dies ist ein GCC-Fehler , der in GCC 9.2 behoben wurde.
Wenn Sie dieses Problem haben, aktualisieren Sie Ihren Compiler. (Sie können beispielsweise ein neues GCC von MSYS2 erhalten.)
quelle
pacman -Syuu
. Es gibt eine Änderung, dass das Terminal (und alle msys2-Programme) geschlossen werden, um fortzufahren. In einer älteren Version werden Sie aufgefordert, dies manuell zu tun. In diesem Fall müssen Sie MSYS2 neu starten und denselben Befehl erneut ausführen, um das Update abzuschließen.random_device
funktioniert immer noch nicht.GCC implementiert rd.entropy () nicht korrekt - es gibt immer 0 zurück (zumindest unter Mac OS X).
Leider scheint es keine Möglichkeit zu geben, zusätzliche Entropie in random_device zu mischen, was wichtig ist, da es normalerweise / häufig (siehe Linux / dev / random und / dev / urandom sowie die Intel RDRAND-Implementierung) einen Pseudozufallszahlengenerator implementiert unter der Haube. Ich möchte in der Lage sein, seine Ausgabe zu verbessern, indem ich etwas injiziere, das ich für zufällig halte, um es mit dem zu mischen, was seine Entropiequelle erzeugt. Da dieses Gerät (oder Kernelmodul) intern einen kryptografischen Algorithmus zum Verarbeiten der Entropiebits implementiert, die es zur Erzeugung seiner Ausgabe erhält, möchte ich diesen Prozess mehr "randomisieren" können, indem ich meine eigenen Daten injiziere, um sie mit irgendetwas zu mischen Entropie, die das Gerät auswählt. Betrachten Sie beispielsweise Java SecureRandom (). Sie können nicht einstellen das Seed (das es tatsächlich in PRNG konvertieren würde), aber es würde glücklich mischen, was Sie bereitstellen, mit dem, was es verwendet, um seine Ausgabe noch mehr zu "randomisieren".
Ich persönlich bevorzuge RDRAND. Eine kleine Assemblybibliothek mit einer kompakten C-Schnittstelle. Hier sind die Referenzen:
David Johnson von Intel erklärt RDRAND zu Stackoverflow
Stackoverflow-Zeiger auf die RDRAND-Bibliotheksquelle für Windows, Linux und Mac OS X.
Intel-Blog über die RDRAND-Bibliothek und ein Download-Link
quelle
random_device
. Wenn es einen Startwert erfordert, dann ist es ein Pseudozufallsgenerator, kein echter Zufallszahlengenerator, wierandom_device
es sein soll./dev/random
. Jetzt weiß ich es besser: eine Datei als Entropiequelle hinzufügen und warum schreibe / dev / random ... . Das XORing der zusätzlichen Entropie in das Ergebnis ist ein guter und effizienter Weg - mit dem Nachteil, explizit zu sein.SecureRandom
sich all dieser Details und Verbesserungen nicht bewusst zu sein und einfach die Standardschnittstelle der Standardklasse unverändert zu verwenden. Ein weiterer Vorteil der Java SecureRandom-API besteht darin, dass sie durch "schlechte" Zufälligkeitseingaben des Benutzers nicht beschädigt werden kann. Die SecureRandom-Ausgabe kann nur durch zusätzliche Eingabe verbessert werden (oder bei gleicher Qualität bleiben).