web-dev-qa-db-fra.com

Pourquoi est-ce que j'obtiens la même séquence pour chaque exécution avec std :: random_device avec mingw gcc4.8.1?

J'utilise le code suivant pour tester la bibliothèque c++ <random>.

Pourquoi est-ce que j'obtiens exactement la même séquence pour chaque exécution de l'exécutable compilé? rd() est-il déterministe lors de la compilation? Comment obtenir une sortie différente pour chaque exécution?

GCC 4.8.1 sur Windows 7 64 bits. Utilisation de la distribution MinGW de http://nuwen.net/mingw.html

EDIT: J'ai testé le même code pièce avec Visual Studio. Il n'y a pas de problème. Les sorties ne sont pas déterministes. Cela pourrait être un bogue dans mingw gcc 4.8.1 que j'ai utilisé.

#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

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

Notez que std :: random_device peut être implémenté en termes de moteur de nombres pseudo-aléatoires si une source non déterministe (par exemple un périphérique matériel) n'est pas disponible pour l'implémentation.

Je m'attendrais à une mise en œuvre décente pour au moins ensemencer le RNG.

Edit: Je soupçonne qu'ils ont délibérément choisi de livrer la même séquence à chaque fois, pour rendre évident le fait que le flux n'était pas aussi aléatoire que promis.

32
Mark Ransom

J'ai reçu une réponse confirmée de STL de MSFT :

Contrairement à VC, GCC n'a pas implémenté random_device de manière non déterministe sous Windows. Boost l'a, vous pouvez donc utiliser Boost.Random.

24
ahala

Vous devrez peut-être passer un paramètre au constructeur:

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

3
user877329
  1. GCC n'implémente pas correctement rd.entropy () - il renvoie toujours 0 (au moins sur Mac OS X).

  2. Malheureusement, il ne semble y avoir aucun moyen de mélanger une entropie supplémentaire dans random_device, ce qui est important car il utilise généralement/souvent (regardez Linux/dev/random et/dev/urandom, et la mise en œuvre Intel RDRAND) implémente un générateur de nombres pseudo-aléatoire sous la capuche. J'aimerais pouvoir améliorer sa sortie en injectant quelque chose que je considère comme aléatoire à mélanger avec tout ce que sa source d'entropie produit. Encore une fois, puisque cet appareil (ou module noyau) implémente en interne un algorithme cryptographique pour traiter les bits d'entropie qu'il obtient pour générer sa sortie, j'aimerais pouvoir "randomiser" ce processus plus en injectant mes propres données pour qu'elles se mélangent à l'entropie choisie par cet appareil. Par exemple, considérez Java SecureRandom (). Il ne vous permet pas de définir la graine (qui en effet convertirait à PRNG), mais il serait heureux de mélanger ce que vous fournissez avec tout ce qu'il utilise pour "randomiser" encore plus sa sortie.

  3. Personnellement, je préfère RDRAND. Une petite bibliothèque d'assemblage avec une interface C compacte. Voici les références:

    David Johnson d'Intel explique RDRAND sur Stackoverflow

    Pointeurs Stackoverflow vers la source de la bibliothèque RDRAND pour Windows, Linux et Mac OS X

    Blog Intel sur la bibliothèque RDRAND et un lien de téléchargement

2
Mouse