12
votes

Générez un nombre aléatoire avec une longueur prédéfinie PHP

J'essaie de créer une fonction à l'aide de mt_rand () afin de générer un nombre vraiment aléatoire, puisque Rand () n'est tout simplement pas suffisant.

Le problème est que j'ai besoin de pré-définir la longueur de la longueur de la Number, disons que j'ai besoin d'un nombre aléatoire à 10 chiffres.

Quoi qu'il en soit, je me découle et c'est ce que j'ai proposé: xxx < P> En théorie qui devrait fonctionner (autant que je puisse dire), mais ce n'est pas le cas. La longueur est complètement aléatoire et jette également des valeurs négatives.

Des idées?


7 commentaires

"Afin de générer un nombre vraiment aléatoire" bien, vous obtiendrez toujours un nombre pseudo-aléatoire. Même la Mersenne Twister ne peut pas vous obtenir un nombre vraiment aléatoire. Le plus proche que vous puissiez obtenir est de aléatoire.org avec leurs données de bruit atmosphérique.


Quoi qu'il en soit, ce n'est pas le problème, mt_rand () est beaucoup plus aléatoire que Rand ().


Rand (min, max) retournera un entier, donc uniquement dans la gamme d'entiers PHP 32 bits sur un système 32 bits ... N'oubliez pas non plus que 0000000001 == 1, votre gamme est donc de 1 à 9999999999, vous voulez. $ min = 1. str_repeat (0, $ long-1)


Aussi, avec aléatoire.org, je ne veux pas avoir à boucler leur site web à chaque fois.


Cela ne fonctionne toujours pas avec la longueur. Il génère toujours des chaînes à 8 chiffres et générer toujours des valeurs négatives.


@Karl .... Je vais répéter: "Rand (min, max) retournera un entier, donc uniquement dans la gamme d'entiers PHP 32 bits sur un système 32 bits"


MT_RAND () ne génère que des nombres aléatoires inférieurs à la valeur MT_GETRANDMAX (). On dit toujours 2 ^ 31 - 1, même sur des systèmes 64 bits. Cela rend efficacement impossible de générer des chaînes de longueur arbitraire avec votre fonction, la longueur maximale peut être de 9 caractères.


11 Réponses :


36
votes

Sauf si vous avez une de ces trucs quantiques statiques, vous ne pouvez pas obtenir un nombre vraiment aléatoire. Sur les OSES basés sur UNIX, toutefois, / dev / urandom fonctionne pour "plus aléatoire", si vous avez vraiment besoin de cela.

Quoi qu'il en soit, si vous voulez un numéro de n-chiffres, c'est exactement ce que vous devrait obtenir: n chiffres individuels. xxx

La raison que votre code existant ne fonctionne pas est parce que 0000 ... 01 est toujours 1 à mt_rand , ainsi que aussi que mt_rand S n'est pas infini. Les nombres négatifs sont des débordements entier.


9 commentaires

Point valide, cependant, je viens d'essayer cela et il ne colle toujours pas de la longueur pour une raison quelconque, il a généré une chaîne 12 chiffres de long.


@Karl: Oui, désolé, j'ai commis une erreur. mt_rand est inclusif. Il suffit de changer le 10 sur 9 .


Cela peut toujours générer des nombres inférieurs à dix chiffres si le premier (et la deuxième, et la troisième ...) est / sont 0.


BTW - Je peux obtenir un nombre aléatoire sans une chose statique quantum - je dois juste observer la nature et la quantifier - nous sommes tous dans un état de changement quantique - par exemple, je peux capturer une carie radioactive assez facilement avec une caméra numérique et un morceau d'americanum (d'un détecteur de fumée). Le hasard n'est pas difficile, c'est juste dure à l'intérieur de la machine.


En fait, Tom, ça ne le fait pas, je viens de générer quelques-uns et à chaque fois que cela a été la longueur correcte (même des temps, il a été démarré avec un 0).


@Tomsmilack: NOPE! Darn Date de frappe à nouveau, hein? :RÉ


Oh, j'ai supposé que ceux-ci seraient utilisés comme des nombres plutôt que de rester comme des chaînes.


Pourquoi pas seulement mt_rand (100000000, 99999999999)?


@Mywetsocks: pas de zéros de premier plan, et pour une fonction générique que vous pouvez transmettre une longueur à, elle (a) ne pas économiser beaucoup et (b) ne fonctionne pas pour 10 chiffres ou plus ( Secure.php.net/manual/fr/function.mt-getrandmax.php ).



0
votes

Vous ne devriez pas commencer par la longueur contraignant les nombres aléatoires. Plutôt accumuler une sortie suffisamment longue, puis la couper à la droite longueur: xxx

Le remplissage doit être là, car même les zéros sont générés de manière aléatoire et doivent être conservés.


2 commentaires

Si votre générateur de nombres aléatoires n'est pas bon, cela pourrait être problématique car vous réduisez votre monde et que les chiffres peuvent répéter dans les groupes - tout dépend de la mise en œuvre. (même peut être dit sur le générateur en premier lieu). Mais j'éviterais ça.


MT_RAND () Accepte deux valeurs entières. Peu importe peu importe si vous écrivez le zéro comme "0" ou "00000", mais ce dernier est le format de nombre octal!



8
votes

court et sucré:

Je suppose que des nombres légitimes, pas des cordes comme 00010. Essayez d'utiliser la taille de votre numéro pour être: p>

  $min = pow(10, $length - 1) ;
  $max = pow(10, $length) - 1;
  return mt_rand($min, $max);   


5 commentaires

Je pense que vous vouliez probablement faire "dix à la puissance de la longueur", pas "la longueur des temps dix".


@Minitech Oui, je frappe Soumettre avant que j'ai fini de modifier et de courir dans CodePad.org


mt_rand () ne prend pas en charge les nombres aléatoires de longueur arbitraire.


@Sven voulez-vous dire que la solution fournie ne fonctionnera pas dans certains cas? Je pense que cela fonctionnera car les variables $ Min et $ maximale contiendront le nombre minimum et maximum de longueur de longueur de longueur. Ainsi, la fonction mt_rand () n'aura qu'une longueur, comme option, pour sa sortie.


mt_rand () ne produit pas de chiffres arbitraires. Il est limité de ne pas créer d'entiers supérieurs à mt_getrandmax () , quelle que soit les valeurs min et max que vous fournissez. Cela rend cette réponse échoue à la plupart des valeurs de $ Longueur que vous pouvez fournir, à l'exception des valeurs comprises entre 1 et environ 7 ou 8. Voir mon commentaire à la question elle-même: Stackoverflow.com/questions/13169025/... .



1
votes
function randomNumber($length) {
    $min = 1 . str_repeat(0, $length-1);
    $max = str_repeat(9, $length);
    return mt_rand($min, $max);   
}
you have your concat 1 in the wrong spot, your range is this for $length=2: {01,99} - sometimes its 01-09, that is represented as 1-9 not 01-09.  Just start from 10: {10,99} will be your range.

1 commentaires

Erreur fatale PHP: non capturée TypeError: mt_rand (): argument n ° 1 ($ min) doit être de type INT, une chaîne donnée dans /workspace/main.php:7 pile trace: # 0 /workspace/main.php(7): mt_rand () # 1 /workspace/main.php(10): randomnumber () # 2 {main} lancé dans /workspace/main.php à la ligne 7



1
votes

Utilisez ceci pour des cordes d'une certaine longueur avec des lettres et des chiffres. Testé.

protected function randomToken($length = 4, $result='') {

    for($i = 0; $i < $length; $i++) {

        $case = mt_rand(0, 1);
        switch($case){

            case 0:
                $data = mt_rand(0, 9);
                break;
            case 1:
                $alpha = range('a','z');
                $item = mt_rand(0, 25);

                $data = strtoupper($alpha[$item]);
                break;
        }

        $result .= $data;
    }

    return $result;
}


1 commentaires

Je pense que vous pouvez simplement utiliser ce code à la place: RETOUR SUBSTR (UNIQID (), 0, $ LIENS);



6
votes

Voici ce que j'utilise: xxx

une ligne, sympa et simple! Le nombre ne commencera jamais avec 0 et permet à 0 à tout autre endroit.


0 commentaires

2
votes
function randomNDigitNumber($digits)
{
  $returnString = mt_rand(1, 9);
  while (strlen($returnString) < $digits) {
    $returnString .= mt_rand(0, 9);
  }
  return $returnString;
}

  The first line ensures that no "0" precedes any number, for instance values like 012, 0598... will be discarded, the rest is easy

0 commentaires

0
votes

En supposant que vous utilisiez une petite gamme et que vous ne voulez pas générer le même numéro deux fois, que diriez-vous:

function random(int $len): int
{
    static $track = [];
    
    $min = 1 . str_repeat(0, $len - 1);
    $max = str_repeat(9, $len);
    $num = mt_rand($min, $max);
    
    // if was generated before, try again
    if (in_array($num, $track))
    {
        return random($len);
    }
    
    // store and return
    return $track[] = $num;
}


0 commentaires

5
votes

doit spécifier la plage de la plage à Rand, si vous avez besoin d'un nombre aléatoire à 4 chiffres, utilisez-le simplement comme xxx


0 commentaires

0
votes

Si l'environnement est local, il n'est pas nécessaire de créer un nombre aléatoire et mt_rand est comme Rand mais quatre fois plus rapide xxx


0 commentaires

0
votes

vu beaucoup de réponses ici, pour votre besoin, j'ai une pièce de code petite et efficace

<?php
$random_no = mt_rand ( 0000000000 , 9999999999 ); 
// this will generate a 10 digit random number
echo $random_no;
?>


0 commentaires