Php 从范围中获取10个随机数的最快方法

Php 从范围中获取10个随机数的最快方法,php,Php,我想从给定的范围内得到10个随机数 我使用下面的代码,但对于更大的范围,它是缓慢的。任何替代方法,使它尽可能快 $rangearr = array_rand(range(1,11892032), 5); $rangearr = implode(",",$rangearr); 只用 $randomnr=array(); $min=1; $max=11892032; 对于($i=0;$i

我想从给定的范围内得到10个随机数

我使用下面的代码,但对于更大的范围,它是缓慢的。任何替代方法,使它尽可能快

$rangearr = array_rand(range(1,11892032), 5);
$rangearr  = implode(",",$rangearr);
只用

$randomnr=array();
$min=1;
$max=11892032;
对于($i=0;$i<10;$i++){
$RANDONNR[]=百万兰特($min,$max);
}
回波内爆(',',$randomnr);
对于唯一编号,请使用以下命令:

$randomnr = array();
$min = 1;
$max = 11892032;
$i = 1;
while($i <= 10) {
    $rand = mt_rand($min, $max);
    if(!in_array($rand,$randomnr)) {
        $randomnr[] = $rand
        $i++;
    }
}
$randomnr=array();
$min=1;
$max=11892032;
$i=1;
而($i只需使用

$randomnr=array();
$min=1;
$max=11892032;
对于($i=0;$i<10;$i++){
$RANDONNR[]=百万兰特($min,$max);
}
回波内爆(',',$randomnr);
对于唯一编号,请使用以下命令:

$randomnr = array();
$min = 1;
$max = 11892032;
$i = 1;
while($i <= 10) {
    $rand = mt_rand($min, $max);
    if(!in_array($rand,$randomnr)) {
        $randomnr[] = $rand
        $i++;
    }
}
$randomnr=array();
$min=1;
$max=11892032;
$i=1;
而($i另一种方式

$arr = array();
$min = 1;
$max = 11892032 + 1; // important +1
for ($i = 0; $i < 10; $i++) {
    $arr[] = (mt_rand() + $min) % $max;
}
$arr=array();
$min=1;
$max=11892032+1;//重要+1
对于($i=0;$i<10;$i++){
$arr[]=(mt_rand()+$min)%$max;
}
睡前阅读:另一种方法

$arr = array();
$min = 1;
$max = 11892032 + 1; // important +1
for ($i = 0; $i < 10; $i++) {
    $arr[] = (mt_rand() + $min) % $max;
}
$arr=array();
$min=1;
$max=11892032+1;//重要+1
对于($i=0;$i<10;$i++){
$arr[]=(mt_rand()+$min)%$max;
}

睡前阅读:

所以我把它放在一起

<?php

// range
$timer = microtime(true);

$rangearr = array_rand(range(1,11892032), 5);
$rangearr  = implode(",",$rangearr);

echo number_format(microtime(true) - $timer, 5) . '<br>';

// fixed range
$timer = microtime(true);

$range = range(1, 11892032);
$rangearr = array_rand($range, 5);
$rangearr  = implode(",",$rangearr);

echo number_format(microtime(true) - $timer, 5) . '<br>';

// for loop
$timer = microtime(true);

$rangearr = [];
for($i = 0; $i < 5; $i++)
{
    $rangarr[] = rand(1, 11892032);
}

echo number_format(microtime(true) - $timer, 5) . '<br>';

我会使用for循环方法!

所以我把它放在了一起

<?php

// range
$timer = microtime(true);

$rangearr = array_rand(range(1,11892032), 5);
$rangearr  = implode(",",$rangearr);

echo number_format(microtime(true) - $timer, 5) . '<br>';

// fixed range
$timer = microtime(true);

$range = range(1, 11892032);
$rangearr = array_rand($range, 5);
$rangearr  = implode(",",$rangearr);

echo number_format(microtime(true) - $timer, 5) . '<br>';

// for loop
$timer = microtime(true);

$rangearr = [];
for($i = 0; $i < 5; $i++)
{
    $rangarr[] = rand(1, 11892032);
}

echo number_format(microtime(true) - $timer, 5) . '<br>';

如果您想要一个单行程序,我会选择for-loop方法!

$min = 1;
$max=11892032;
echo implode(',', array_map(function()use($min,$max){return mt_rand($min, $max);},range(0,9)));

如果您想要一个班轮:

$min = 1;
$max=11892032;
echo implode(',', array_map(function()use($min,$max){return mt_rand($min, $max);},range(0,9)));

您也可以尝试下面的代码段,它比
range()
快得多,如果您提供一个几乎安全的整数,或者在本例中是一个没有小数点的浮点,您还可以在返回之前将其强制转换为int

我还检查了循环中的Doublets,因此如果您想要五个唯一的数字(
$randomNumberCount=5;
),您将得到它

注意:如果发生错误,请阅读我的代码中的注释

工作示例:

function secure_rand( $min, $max ) {
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
        throw new RuntimeException("Bad range");
    }

    // if mcrypt is enabled try this
    //$bytes = mcrypt_create_iv( 4, MCRYPT_DEV_URANDOM );

    // if mcrypt is not enabled on your server, you can use this
    $bytes = openssl_random_pseudo_bytes( 4 );

    // if mbstring is not enabled, you can also use iconv_strlen
    if ($bytes === false || mb_strlen($bytes, '8bit') != 4) {
        throw new RuntimeException("Unable to get 4 bytes");
    }

    $ary = unpack("Nint", $bytes);
    $val = $ary['int'] & 0x7FFFFFFF;   // 32-bit safe
    $fp = $val / 2147483647.0; // convert to [0,1]
    // if you really need a type of int take this
    // return (int) round($fp * $diff) + $min;
    // otherwise it will return a float without decimal numbers
    return round($fp * $diff) + $min;
}


$randomNumbers = array();
$randomNumberCount = 5;
$min = 1;
$max = 11892032;

while( count( $randomNumbers ) < $randomNumberCount ) {
    $rand = secure_rand( $min, $max );
    // check for doublettes
    if( in_array( $rand, $randomNumbers ) ) continue;

    $randomNumbers[] = $rand;
}

$randomNumbers = implode( ",", $randomNumbers );

echo $randomNumbers;
功能安全等级($min,$max){
$diff=$max-$min;
如果($diff<0 | |$diff>0x7fffff){
抛出新的RuntimeException(“坏范围”);
}
//如果启用了mcrypt,请尝试此操作
//$bytes=mcrypt\u create\u iv(4,mcrypt\u DEV\u uradom);
//如果服务器上未启用mcrypt,则可以使用此选项
$bytes=openssl_随机_伪_字节(4);
//如果未启用mbstring,也可以使用iconv\U strlen
如果($bytes==false | | mb|strlen($bytes,'8bit')!=4){
抛出新的RuntimeException(“无法获取4字节”);
}
$ary=解包(“Nint”,$bytes);
$val=$ary['int']&0x7FFFFFFF;//32位安全
$fp=$val/2147483647.0;//转换为[0,1]
//如果你真的需要一种int类型,就用这个
//返回(整数)轮($fp*$diff)+$min;
//否则,它将返回不带小数的浮点
返回轮($fp*$diff)+$min;
}
$randomNumbers=array();
$randomNumberCount=5;
$min=1;
$max=11892032;
while(计数($randomNumbers)<$randomNumberCount){
$rand=安全等级($min,$max);
//检查有无双重测试
如果(在数组中($rand,$randomNumbers))继续;
$randomNumbers[]=$rand;
}
$randomNumbers=内爆(“,”,$randomNumbers);
回音数字;

您也可以尝试下面的代码段,它比
range()快得多。
如果您提供一个几乎安全的整数,或者在本例中是一个不带小数点的浮点,您还可以在返回之前将其强制转换为int

我还检查了循环中的Doublets,因此如果您想要五个唯一的数字(
$randomNumberCount=5;
),您将得到它

注意:如果发生错误,请阅读我的代码中的注释

工作示例:

function secure_rand( $min, $max ) {
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
        throw new RuntimeException("Bad range");
    }

    // if mcrypt is enabled try this
    //$bytes = mcrypt_create_iv( 4, MCRYPT_DEV_URANDOM );

    // if mcrypt is not enabled on your server, you can use this
    $bytes = openssl_random_pseudo_bytes( 4 );

    // if mbstring is not enabled, you can also use iconv_strlen
    if ($bytes === false || mb_strlen($bytes, '8bit') != 4) {
        throw new RuntimeException("Unable to get 4 bytes");
    }

    $ary = unpack("Nint", $bytes);
    $val = $ary['int'] & 0x7FFFFFFF;   // 32-bit safe
    $fp = $val / 2147483647.0; // convert to [0,1]
    // if you really need a type of int take this
    // return (int) round($fp * $diff) + $min;
    // otherwise it will return a float without decimal numbers
    return round($fp * $diff) + $min;
}


$randomNumbers = array();
$randomNumberCount = 5;
$min = 1;
$max = 11892032;

while( count( $randomNumbers ) < $randomNumberCount ) {
    $rand = secure_rand( $min, $max );
    // check for doublettes
    if( in_array( $rand, $randomNumbers ) ) continue;

    $randomNumbers[] = $rand;
}

$randomNumbers = implode( ",", $randomNumbers );

echo $randomNumbers;
功能安全等级($min,$max){
$diff=$max-$min;
如果($diff<0 | |$diff>0x7fffff){
抛出新的RuntimeException(“坏范围”);
}
//如果启用了mcrypt,请尝试此操作
//$bytes=mcrypt\u create\u iv(4,mcrypt\u DEV\u uradom);
//如果服务器上未启用mcrypt,则可以使用此选项
$bytes=openssl_随机_伪_字节(4);
//如果未启用mbstring,也可以使用iconv\U strlen
如果($bytes==false | | mb|strlen($bytes,'8bit')!=4){
抛出新的RuntimeException(“无法获取4字节”);
}
$ary=解包(“Nint”,$bytes);
$val=$ary['int']&0x7FFFFFFF;//32位安全
$fp=$val/2147483647.0;//转换为[0,1]
//如果你真的需要一种int类型,就用这个
//返回(整数)轮($fp*$diff)+$min;
//否则,它将返回不带小数的浮点
返回轮($fp*$diff)+$min;
}
$randomNumbers=array();
$randomNumberCount=5;
$min=1;
$max=11892032;
while(计数($randomNumbers)<$randomNumberCount){
$rand=安全等级($min,$max);
//检查有无双重测试
如果(在数组中($rand,$randomNumbers))继续;
$randomNumbers[]=$rand;
}
$randomNumbers=内爆(“,”,$randomNumbers);
回音数字;


@Vishnu不,你必须检查它。如果你在一组10个从1到100多万的数字中得到相同的数字,我会吃掉我想象中的帽子。@Amarnasan仍然是可能的(:@Vishnu当我的答案帮助你时,把它标记为正确的。@JannisM:你忘了一个括号:
如果(!in_数组($rand,$randomnr)-->)@Vishnu不,你必须检查它。如果你在一组10个数字中得到相同的数字,从1到100多万,我会吃掉我想象中的帽子。@Amarnasan仍然是可能的(:@Vishnu当我的答案帮助你时,把它标记为正确。@JannisM:你忘了一个括号:
如果(!in_array($rand,$randomnr)-->)如果每个人都像你一样理解一行代码,那么PHP中的所有内容都可以用一行代码来完成,我看到三行代码,我很喜欢though@Dale:但是看看前两行是什么!如果你真的想要一行,你可以替换array\u map闭包中的$min、$max值,但是我想说明的是,你不需要将闭包硬编码为ma让它工作吧我不再喜欢它了如果每个人都像你一样理解一行程序,PHP中的所有东西都可以用一行程序来完成