Question

Je sais que le simple fait d'utiliser rand() est prévisible, si vous savez ce que vous faites et avez accès au serveur.

J'ai un projet qui est très dépend du choix d’un nombre aléatoire aussi imprévisible que possible.Je recherche donc des suggestions, soit d'autres fonctions intégrées, soit des fonctions utilisateur, qui peuvent générer un mieux nombre aléatoire.

J'en ai profité pour faire un petit test :

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

J'ai trouvé que les résultats étaient uniformément répartis et qu'il existe une tendance étrange dans le nombre de fois que chaque numéro est généré.

Était-ce utile?

La solution

Ajouter, multiplier ou tronquer une source aléatoire médiocre vous donnera un résultat aléatoire médiocre.Voir Introduction au hasard et aux nombres aléatoires pour une explication.

Vous avez raison à propos de la fonction PHP rand().Voir le deuxième chiffre sur Analyses statistiques pour une illustration saisissante.(Le premier chiffre est frappant, mais il a été dessiné par Scott Adams, et non tracé avec rand()).

Une solution consiste à utiliser un véritable générateur aléatoire tel que random.org.Un autre, si vous êtes sous Linux/BSD/etc.est d'utiliser /dev/aléatoire.Si le caractère aléatoire est critique pour la mission, vous devrez utiliser un générateur aléatoire matériel.

Autres conseils

random.org dispose d'une API à laquelle vous pouvez accéder via HTTP.

Random.org est un véritable service de nombre aléatoire qui génère un aléatoire via le bruit atmosphérique.

Je me méfierais de l'impression d'aléatoire :il y a eu de nombreuses expériences dans lesquelles les gens choisiraient la distribution la moins aléatoire.Il semble que l’esprit ne soit pas très doué pour produire ou estimer le hasard.

Il y a de bons articles sur le hasard sur Fourmilab, dont un autre vrai générateur aléatoire.Peut-être pourriez-vous obtenir des données aléatoires des deux sites, donc si l'un est en panne, vous avez toujours l'autre.

Fourmilab propose également un programme d'essai pour vérifier le caractère aléatoire.Vous pouvez l'utiliser pour vérifier vos différents programmes myRand().

Quant à votre dernier programme, si vous générez 10 000 valeurs, pourquoi ne choisissez-vous pas la valeur finale parmi les 10 000 ?Vous vous limitez à un sous-ensemble.De plus, cela ne fonctionnera pas si vos $min et $max sont supérieurs à 10 000.

Quoi qu'il en soit, le caractère aléatoire dont vous avez besoin dépend de votre application.rand() conviendra à un jeu en ligne, mais pas à la cryptographie (tout ce qui n'est pas minutieusement testé avec des programmes statistiques ne conviendra de toute façon pas à la cryptographie).Soyez le juge!

Variation sur @KG, en utilisant les millisecondes depuis EPOCH comme graine pour rand ?

Une autre façon d'obtenir des nombres aléatoires, similaire dans son concept à l'obtention de l'UUID

PHP version 5.3 et supérieure

openssl_random_pseudo_bytes(...)

Ou vous pouvez essayer ce qui suit bibliothèque en utilisant RFC4122

Un nouveau PHP7 il existe une fonction qui fait exactement ce dont vous aviez besoin :il génère entiers pseudo-aléatoires cryptographiquement sécurisés.

int random_int ( int $min , int $max )

Génère des entiers aléatoires cryptographiques qui conviennent à une utilisation où les résultats impartiaux sont essentiels (c.-à-d.mélanger un jeu de poker).

Pour une explication plus détaillée sur PRNG et CSPRNG (et leur différence) ainsi que pour pourquoi votre approche originale est en fait une mauvaise idée, veuillez lire mon une autre réponse très similaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top