【问题标题】:Random ID/Number Generator in PHPPHP 中的随机 ID/数字生成器
【发布时间】:2010-07-27 20:09:16
【问题描述】:

我正在我的数据库中构建一个“代理 ID”列表,并满足以下要求:

  1. ID 必须为 9 位数字(仅限数字)
  2. ID 不能包含超过 3 个相同的数字。
  3. ID 不能连续包含超过 2 个相同的数字(即 887766551;不能有 888..)

到目前为止,我已经完成了第 1 部分,但在上面的第 2 和第 3 部分中挣扎。我的代码如下。

function createRandomAGTNO() {
    srand ((double) microtime( )*1000000);
    $random_agtno = rand(100000000,900000000);
    return $random_agtno;
}

// Usage
$NEWAGTNO = createRandomAGTNO();

有什么想法吗?

【问题讨论】:

  • 一个微优化... 将您的rand 调用从100112233 绑定到998877665(可能的最低和最高匹配,因此您减少了很多不必要的尝试)。 ..
  • +1 好想法 ircmaxell! ..

标签: php random


【解决方案1】:
  1. 不要不要像这样在每次调用时重新播种 RNG,除非您想彻底破坏随机数的安全性。
  2. 除非您的 PHP 非常旧,否则您可能根本不需要重新播种 RNG,因为 PHP 在启动时会为您播种,并且在极少数情况下您需要用您的其中一个替换种子自己选择。
  3. 如果您可以使用,请使用mt_rand 而不是rand。我的示例将使用mt_rand

至于其余部分 - 您可能会想出一个非常聪明的数字映射,将线性范围内的数字映射到您想要的形式的数字上,但让我们用蛮力来代替。这是其中之一,是的,运行时间的理论上限是无限的,但预期运行时间是有限的并且非常小,所以不要太担心。

function createRandomAGTNO() {
  do {
    $agt_no = mt_rand(100000000,900000000);
    $valid = true;
    if (preg_match('/(\d)\1\1/', $agt_no))
      $valid = false; // Same digit three times consecutively
    elseif (preg_match('/(\d).*?\1.*?\1.*?\1/', $agt_no))
      $valid = false; // Same digit four times in string
  } while ($valid === false);
  return $agt_no;
}

【讨论】:

  • 由于循环中的正则表达式,我的直觉说 eiww。但是话又说回来,它们都是轻型正则表达式,并且您为每个“尝试”保存多个 rand 调用(甚至 array_randshuffle 函数在内部多次调用它)......所以它似乎没有几乎和本能所暗示的一样糟糕(事实上,它看起来相当不错)...+1...
  • 我会说在数学上这样做是最快的。正则表达式无法击败它。
  • 试试看。发布的正则表达式解决方案平均为每次运行 0.00006 秒,而您的平均为 0.00017 秒(我的平均为 0.00015 秒)......哦,平均每次运行总共超过 100000 次。所以就剪切速度而言,看起来正则表达式占了上风……
  • @ircmaxell 它可以工作,因为十分之九,我的整个循环只运行 一次 :)
  • @hobbs:非常正确。但是 100 个轻循环和 1 个重循环之间的差异仍然不是微不足道的。所以我认为归结为正则表达式比rand 调用更轻。如果反过来,另一种方法会“更快”。但以这样的速度,谁真正在乎(除非你产生了数十亿个)......
【解决方案2】:

对于第二个条件,你可以像这样创建一个数组

$a = array( 0,0,1,1,2,2,3,3.....,9,9 );

并获取随机元素:array_rand()(参见手册)获取数字,将其附加到您的 ID 并通过在索引处取消设置来从源数组中删除值。

通常,此解决方案也是第三个条件,但此解决方案排除了所有可能和可接受的三位数字的 ID

【讨论】:

【解决方案3】:

想到的第一个解决方案是递归函数,它简单地测试您的三个需求并在其中任何三个失败时重新启动。不是最有效的解决方案,但它会起作用。我在下面写了一个未经测试的版本。可能无法正常运行,但您应该从中了解基本概念。

function createRandomAGTNO(){
  srand ((double) microtime( )*1000000);
  $random_agtno = rand(100000000,900000000);

  $random_agtno_array = explode('', $random_agtno);

  foreach($random_agtno_array as $raa_index => $raa){
    if($raa == $random_agtno_array[$raa_index + 1] && raa == $random_agtno_array[$raa_index + 2]) createRandomAGTNO();

    $dup_match = array_search($raa, $random_agtno_array);
    if($dup_match){
      unset($random_agtno_array[$dup_match]);
      if(array_search($raa, $random_agtno_array)) createRandomAGTNO();
    };
  }

  return $random_agtno;
}

【讨论】:

    【解决方案4】:

    试试这个代码:

    <?php
    function createRandomAGTNO() {
        //srand ((double) microtime( )*1000000);
        $digits = array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ,1, 2, 3, 4, 5, 6, 7, 8, 9, 0 );
        shuffle($digits);
        $random_agtno = 0;
        for($i = 0; $i < 9; $i++)
        {
            if($i == 0)
            {
                while($digits[0] == 0)
                    shuffle($digits);
            }
            /*if($i >= 2)
            {
                while(($random_agtno % 100) == $digits[0])
                    shuffle($digits);
            }*/
            $random_agtno *= 10;
            $random_agtno += $digits[0];
            array_splice($digits, 0, 1);
        }
        return $random_agtno;
    }
    
    for($i = 0; $i < 1000; $i++)
    {
        $NEWAGTNO = createRandomAGTNO();
        echo "<p>";
        echo $NEWAGTNO;
        echo "</p>";
    }
    ?>
    

    祝你好运!

    编辑: 删除了对 srand() 的调用并注释掉了“if($i >= 2)”代码,无论如何这是不可能的,在这里。

    【讨论】:

    • 这里的优点是; 1)您不使用字符串/字符,而仅使用数字。 2)您使用 PHP 中内置的 shuffle() 命令,因此速度很快。我不认为你真的需要使用 srand(),现在我明白了.. :)
    • 您好 ircmaxell,我无法真正理解您的意思。检查更新的代码。从 1000 个数字中寻找违反规则的输出,因为我找不到。
    • 至于三位数 - 如果此代码从上述数组中获取数字,我们如何获得相同数字的 3 倍?
    • 对我的观点进行监督。但它也不符合一个数字最多出现 3 次的要求(因此只会生成可能数字的一小部分)......
    • 你确定吗?其他人可以证实 ircmaxell 的论点吗?
    猜你喜欢
    • 2011-06-14
    • 2014-05-18
    • 2011-05-20
    • 1970-01-01
    • 2017-09-03
    • 2023-04-06
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多