[PHP] Prédire à l’avance les nombres aléatoires !

Salut la compagnie,

 

Oui je sais, je viens encore vous montrer du Dev ... et j'en suis totalement désolé pour vous, m'enfin en ce moment c'est mon truc ;) si vous êtes sages on verra des sujets un peu plus accessibles très bientôt !

Alors aujourd'hui, je vais probablement déterrer de vieux os, mais j'avais envie de vous faire part de ma découverte du jour !

Si je vous présente ce code php:

print rand(1, 100);

Vous me direz ... que j'affiche ici un nombre aléatoire entre 1 et 100 !
Et vous aurez très probablement raison !

Ici, je récupère 67, 11, 74, 22, 98, ... etc ...
C'est là, que vous vous demandez très probablement, comment il est possible de deviner à l'avance, quelque chose qui est "aléatoire"

 

L'aléatoire

Tout d'abord, il est important de rappeler que l'aléatoire n'existe pas ...
La plupart des fonctions censées retourner une valeur aléatoire, vont s'appuyer sur des données changeantes d'un environnement à un autre :

  • La date
  • L'heure
  • Le pourcentage de CPU utilisés
  • Le pourcentage de la Ram Utilisée
  • Le nombre de fichier créés dans l'heure 
  • L'id du processus
  • ... etc ...

Aussi, normalement il est très difficile de prédire à un instant T, la valeur retournée par une fonction qui calcule de l'aléatoire !

Un petit exemple simple pour calculer un nombre aléatoire

"Donnes moi un chiffre entre 1 et 50"

Si je prends l'année (2017), le jour (20), le mois (11), l'heure (19), les minutes (42) et les secondes (52).

Si je les multiplie tous ensemble :
2017 x 20 x 11 x 19 x 42 x 52
J'obtiens : 18 413 435 040

Que je multiplie ensuite par le % d'utilisation de mon processeur, de ma mémoire vive


soit 18413435040 x 8% x 25%3682687008000

 

Comme je cherche un chiffre entre 1 et 50, je vais prendre mes 3682687008000 Je vais extraire les chiffres ou les nombres qui sont compris entre 1 et 50:
3682687008000  => 36 26 008 000

Je supprime tous les "doublons" : 36 8 26 8 7 008 000

J'additionne le tout : 36 + 27 + 7 = 69
Et je le divise autant de fois par 2 qu'il n'en faut pour être en à la fois en dessous du maximum et au-dessus du minimum : 69 / 2 : 34.5

Si je ne parviens pas à un nombre en dessous du maximum ou du minimum (ce qui n'est pas le cas dans mon exemple), je retourne au choix le maximum ou le minimum ;)

 

Les cas d'utilisation de l'aléatoire

Nous utilisons l'aléatoire un peu partout sans nous en rendre compte ...

Pouvoir faire du prédictif est sans intérêt dans des cas comme :

  • Les fonds d'écrans qui changent
  • Les intelligences artificielles que nous essayons de rendre plus humaines !

Mais aussi, sur des sujets un peu plus ... hard !

  • Une loterie en ligne ... connaitre un instant gagnant n'est pas mal non ?
  • La génération d'un mot de passe temporaire ?
    Ba oui tant qu'à faire ... si l'on ne connaît pas le mot de passe d'une personne ... mais qu'on peut générer un mot de passe temporaire ce n'est pas mal non plus ;)

Rand et SRand ...

la fonction PHP n'a pas été correctement construite ... aussi en appelant la fonction "srand()", vous aurez la possibilité de connaitre par avance les prochaines valeurs aléatoires ...

J'ai ici volontairement, réalisé 2 exemples d'appel de la fonction "rand" de PHP ...
Pour chacun de mes exemples, j'ai appelé la fonction "srand" ...
Vous remarquerez ainsi que chaque fois que j'appelle "srand", les nombres aléatoires récupérés reviennent !

Qu'est-ce que fait cette fameuse fonction "srand" :
http://php.net/manual/fr/function.srand.php

Celle-ci initialise, le générateur de nombre aléatoires !
Un générateur suivant toujours la même logique ... renverra toujours les mêmes nombres à chaque remise à 0 !

 

Conclusion :

La fonction rand suit toujours la même logique ... à chaque réinitialisation via srand, nous obtenons les mêmes nombres, et dans le même ordre !
Je vous recommande donc d'éviter d'utiliser srand et rand dans vos scripts !
Côté sécu :
Il suffit pour un pirate de dissimuler dans script php un srand, et hop le pirate pourra lire dans l'avenir !

Partagez ce contenu

2 comments

  • Léger comme article. Pourquoi ne pas pousser sur la fonction mt_rand (et par extension l’algo mersenne twister) ?

    Si vous cherchez une alternative fiable, utilisable pour de la crypto (générer des iv et autres), alors utiliser OpenSSL (openssl_random_pseudo_bytes())

    • Bonjour Louis ;)
      Tout d’abord merci pour cette appréciation de l’article.

      L’idée de départ était de tout simplement constater un mécanisme interne de PHP.
      Bien entendu il y a un certain nombre de nouvelles fonctions alternatives qui ont vu le jour.

      Et j’aurais également pu parler de « Mersenne Twister » (que je viens de découvrir grâce à ton commentaire ;) ).

      Un algo né en 1997 ( mais pas en Février ;) ).
      Bref, j’ai préféré faire un article simple et sans prise de tête, comme beaucoup de mes articles.

Laisser une réponse

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *