I'm trying to create a function using mt_rand() in order to generate a truly random number, since rand() just isn't suffice.

The problem is I need to pre-define the length of the number, say I need a 10 digit random number.

Anyway, I've been messing around and this is what I've come up with:

`` function randomNumber(\$length) {\$min = str_repeat(0, \$length-1) . 1;\$max = str_repeat(9, \$length);return mt_rand(\$min, \$max);}``

In theory that should work (as far as I can tell), but it doesn't. The length is completely random and it also throws out negative values.

Any ideas?

Unless you have one of those quantum-static thingies, you can't get a truly random number. On Unix-based OSes, however, `/dev/urandom` works for "more randomness", if you really need that.

Anyway, if you want an n-digit number, that's exactly what you should get: n individual digits.

``````function randomNumber(\$length) {
\$result = '';

for(\$i = 0; \$i < \$length; \$i++) {
\$result .= mt_rand(0, 9);
}

return \$result;
}
``````

The reason your existing code isn't working is because `0000...01` is still `1` to `mt_rand`, and also that `mt_rand`'s range isn't infinite. The negative numbers are integer overflows.

Short and sweet:

I'm assuming only legitimate numbers, not strings like 00010. Try useing the size of your number to be:

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

The only one that doesn't work is when length is 1, a single digit number '0' won't be a possible value to be returned.

You shouldn't start with the length constraining the random numbers. Rather accumulate a long enough output, then cut it to the right length:

``````while (strlen(\$value) < \$length) {
}
// as pairs of five were added before, eventually remove some again
return substr(\$value, 0, \$length);
``````

The padding should be there, because even zeros are randomly generated and should be retained.

``````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.

Thank you for this example. I have added letters to the simplicity. This works great for me as I am using this with additional tokens for validation.

``````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, 26);

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

\$result .= \$data;
}

return \$result;
}
``````

Here is what I'm using:

``````function random_number(\$length)
{
return join('', array_map(function(\$value) { return \$value == 1 ? mt_rand(1, 9) : mt_rand(0, 9); }, range(1, \$length)));
}
``````

One line, nice and simple! The number will never start with 0 and allows 0 at any other place.

``````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

Top