创建随机数并确保它是唯一的

时间:2019-02-22 22:28:53

标签: php

在我的系统中,每个客户都有自己的文件夹,该文件夹的名称由rand()函数生成。

我想确保$ random变量的值始终保持唯一。我创建了以下代码:

  1. 生成随机数
  2. 检查是否存在具有唯一值的文件夹
  3. 如果存在,则生成新号码
  4. 如果不存在带有随机值名称的mkdir

但是我不确定它是否可以正常工作,并且是执行上述步骤的有效方法。

$random = rand(pow(10, 3-1), pow(10, 3)-1);
$path_validator = 'build/'.$random;
if(is_dir($path_validator)) {
    $random = rand(pow(10, 3-1), pow(10, 3)-1);
}
else
{
   mkdir('build/crm/'.$random, 0777);
}

$random必须是3位随机数字

3 个答案:

答案 0 :(得分:1)

预选赛

1)因为您已经在检查该值是否存在,所以就其比较器而言,它的唯一性并不重要。

2)因为只需要一个“ 3位数”数字,所以在计算规模上只有1000种可能性使得对 unique 值的请求毫无意义。东西的。

答案

因此,您可以简单地使用mt_rand,因为:

  

许多较早的libcs​​的随机数生成器具有可疑或未知的特征,并且运行缓慢。 mt_rand()函数可以替代较早的rand()。它使用»Mersenne Twister使用具有已知特征的随机数生成器,该生成器将产生比libc rand()平均提供的速度快四倍的随机数。

由于您正在寻找一组数字范围,因此可以在mt_rand函数调用中简单地设置此范围。

因此:

代码

// Below lines are only to show the parts to generate $random var. 
// $random = mt_rand(0,999); //generate random number between 0 and 999
// $random = sprintf('%03d', $random); //forces value to 3-digits. ie: 005
//
// Real code begins here:
do {
    $random = sprintf('%03d',mt_rand(000,999));
    $path_validator = 'build/'.$random;
    clearstatcache(); // the directory checker result is cached.
}
while(is_dir($path_validator) || !mkdir('build/crm/'.$random, 0777));

(另请参见sprinf

注意:

  • 范围很小-1000次迭代很小。平方这个数字。
  • 在创建具有0777特权的文件夹时要格外小心。
  • 请特别注意文件夹竞争情况,在这种情况下,PHP可以检查文件夹的存在,然后在并发* PHP进程(例如另一个实例)创建该文件夹之前发现它不存在。
  • 在检查文件夹是否存在时,请小心使用PHP Caching the results
  • 尽管mt_rand的随机性比rand的高,但两个用户都将生成相同的3位数值的可能性仍然较高。被警告!!

答案 1 :(得分:0)

只需使用GUID。 http://php.net/manual/en/function.com-create-guid.php

它很可能是唯一的。

答案 2 :(得分:0)

单线:)

while(!is_dir($id = uniqid()) && !mkdir($id));

3位数字:

while(!is_dir($id = rand(100,999)) && !mkdir($id));

编辑(防弹-希望如此):

while(count(glob('*', GLOB_ONLYDIR))<1000 && !@mkdir('sub.' . rand(100,999) . '.domain.com'));

说明:

如果存在1000个目录,将立即中止。

@mkdir尝试 创建目录。如果失败,则mkdir将返回false,因此循环继续进行。

不再有is_dir来防止同时执行竞速条件。

示例:

鲍勃检查is_dir('333')

乔检查is_dir('333')

Bob尝试创建目录“ 333”-成功。

Jeo尝试创建目录'333'-失败。