11
votes

Réel générateur C # aléatoire

  Random ran = new Random();
  byte tmp = (byte)ran.Next(10);
Is there an alternative to this code?
It does not seem to have fully random behavior.

0 commentaires

3 Réponses :


15
votes

Il y a plusieurs raisons pour lesquelles cela pourrait se produire. Un problème courant est de créer plusieurs instances de la classe aléatoire dans un programme. Lorsque vous utilisez la classe aléatoire , vous ne devez créer qu'une seule instance et générer des chiffres à partir de ceux-ci. L'article Créer de meilleurs numéros aléatoires en C # a une bonne explication de Pourquoi et explique pourquoi ne pas faire cela pourrait conduire à un problème.

Un autre scénario commun accède à l'objet de classe aléatoire à partir de plusieurs threads. System.Random n'est pas le fil de sécurité (voir le REMARQUES SECTION de la documentation de aléatoire ) et peut donc conduire à un comportement inattendu et indésirable. Si vous l'utilisez dans un environnement multi-threadé, vous devez vous assurer d'utiliser une forme de verrouillage pour empêcher plusieurs threads en essayant de générer des nombres aléatoires en même temps.

Pour plus degrés de sécurité et de randomneur, vous pouvez utiliser un générateur de nombres aléatoires sécurisé cryptographiquement. System.Security.Cryptography.rngCryptoserviceProvider . Notez que l'utilisation d'un générateur de nombres aléatoires plus sécurisé entraînera une pénalité de performance par rapport à system.random .

Si vous n'avez pas besoin de quelque chose de cryptographiquement sécurisé, mais je veux toujours quelque chose qui est plus "aléatoire" que la classe aléatoire que vous pouvez explorer à l'aide d'autres PRNG tels que Mersenne Twister. Il existe de nombreuses options, chacune avec différentes caractéristiques et profils de performance. Que vous choisissez est fortement dépendante de votre objectif.


6 commentaires

Non, le problème est instanciant d'une nouvelle instance aléatoire pour chaque appel suivant (). Une erreur souvent commise.


@Thorham - tandis que cela peut être le cas, il ne peut pas être interprété par la question. La question est un simple extrait, il ne peut être exécuté qu'une seule fois, peut-être avec chaque instanciation de l'application, c'est que tout le monde devine. J'agissais de l'hypothèse que l'OP est pas Création d'un nouvel objet aléatoire pour chaque itération d'une boucle ou de quelque chose comme ça. Basé sur l'un des commentaires des OPS, je dirais également que ma réponse s'attaque à la question réelle, que le résultat n'était pas assez "aléatoire". Ils couraient une sorte d'analyse statistique. Pour cela, vous voulez un meilleur générateur aléatoire.


@Thorham - En outre, je doute fortement que c'est la "mauvaise réponse" puisqu'elle est celle que l'OP a accepté. Il peut être ou non la meilleure réponse que j'aurais certainement pu l'élargir plus, mais que la question était vague, j'ai essayé de lui répondre de manière plus générale. Mais dire que c'est incorrect semble un peu une portée. Sans plus de code de l'OP, il n'existe aucun moyen de diagnostiquer le problème plus loin, il peut s'agir de créer de nouvelles instances, mais cela aurait peut-être aussi facilement été causé par l'utilisation de la même instance de aléatoire dans plusieurs threads. , ou peut-être qu'ils viennent de générer trop de 4 .


Peut-être que tu as raison. Je vais supprimer le vote Down, mais vous devez éditer la réponse (cela ne me laissera pas autrement). Cependant, en général, ce n'est pas une bonne idée de recommander le RngCryptoServiceProvider. C'est lent et potentiellement épuisable. Le Linux / Dev / Random et / Dev / Urandom en sont des exemples de ceci. Lorsque le système est sorti de l'entropie, on verrouille aléatoire et Urandom produira des numéros de qualité de merde. Si la sécurité n'est pas une chose, n'utilisez pas de crypto, à moins que vous n'ayez pas besoin de nombreux chiffres. Si la qualité et la vitesse statistiques sont nécessaires (mais pas de sécurité), mettez en œuvre quelque chose comme PCG ou Xoshiro.


@Thorham - J'ai mis à jour la réponse, j'espère être plus clair, etc. En ce qui concerne la recommandation de la RNGCryptoServiceProvider - il est recommandé si le besoin est la sécurité cryptographique - des algorithmes tels que PCG, Xoshiro, Mersenne Twister, etc. ne sont pas sécurisés de manière cryptographique. . Note latérale supplémentaire, ni PCG ou Xoshiro n'existait à l'époque où j'ai écrit cette réponse :)


Votre réponse est très améliorée! Et oui, tu as raison. Ces générateurs que j'ai mentionnés n'existaient pas encore. Je suppose que j'ai manqué la date de publication.



0
votes

Vous pouvez également considérer l'API aléatoire.org

http://www.random.org/clients/http/


0 commentaires

1
votes

Cela pourrait être plus simple que cela. Si vous pouvez cette méthode dans une boucle serrée:

Random ran = new Random();

for (int i = 0; i < 1000; i++)
{
   byte tmp;            
   tmp = (byte)ran.Next(10);
}


2 commentaires

Je simule une statistique avec une probabilité de 10% pour générer 0-10 et voir combien de fois 0 généré


@Domination: soyez prudent. Vous générez des nombres 0-9. 10 ne sera jamais généré comme la limite supérieure exclusive.