简体   繁体   English

PHP中的随机ID /数字生成器

[英]Random ID/Number Generator in PHP

I am building a list of "agent id's" in my database with the following requirements: 我在数据库中建立具有以下要求的“代理ID”列表:

  1. The ID must be 9 digits long (numeric only) ID必须为9位数字(仅限数字)
  2. The ID may not contain more than 3 of the same number. 该ID最多可以包含3个相同的数字。
  3. The ID may not contain more than 2 of the same number consecutively (ie 887766551; cannot have 888..) 该ID不能连续包含两个以上相同的数字(即887766551;不能有888 ..)

So far I have part 1 down solid but am struggling with 2 and 3 above. 到目前为止,我已经稳固了第1部分的内容,但是在第2部分和第3部分方面却遇到了困难。 My code is below. 我的代码如下。

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

// Usage
$NEWAGTNO = createRandomAGTNO();

Any ideas? 有任何想法吗?

  1. Do not re-seed the RNG on every call like that, unless you want to completely blow the security of your random numbers. 不要重新播种的RNG像每一个电话,除非你想完全吹你的随机数的安全性。
  2. Unless your PHP is very old, you probably don't need to re-seed the RNG at all, as PHP seeds it for you on startup and there are very few cases where you need to replace the seed with one of your own choosing. 除非您的PHP很旧,否则您可能根本不需要重新播种RNG,因为PHP在启动时为您播种了种子,在极少数情况下,您需要用自己选择的一种来替换种子。
  3. If it's available to you, use mt_rand instead of rand . 如果您可以使用它,请使用mt_rand而不是rand My example will use mt_rand . 我的示例将使用mt_rand

As for the rest -- you could possibly come up with a very clever mapping of numbers from a linear range onto numbers of the form you want, but let's brute-force it instead. 至于其余的-您可能会想出一个非常聪明的数字映射,将线性范围内的数字映射到所需形式的数字上,但是让我们蛮力吧。 This is one of those things where yes, the theoretical upper bound on running time is infinite, but the expected running time is bounded and quite small, so don't worry too hard. 是的,这是其中之一,运行时间的理论上限是无限的,但是预期的运行时间是有界的并且很小,因此不必太担心。

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;
}

For second condition, you can create an array like this 对于第二个条件,您可以创建一个像这样的数组

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

and get random elements: array_rand() (see manual) to get digit, append it to your ID and remove value from source array by unsetting at index. 并获取随机元素:array_rand()(请参见手册)以获取数字,将其附加到您的ID并通过在索引处取消设置从源数组中删除值。

Generally, this solving also third condition, but this solution excludes all ID's with possible and acceptable three digits 通常,此解决方案也是第三个条件,但是此解决方案排除了所有ID的可能和可接受的三位数

The first solution that comes to mind is a recursive function that simply tests your three requirements and restarts if any three of them fail. 我想到的第一个解决方案是一个递归函数,该函数仅测试您的三个需求并在其中三个需求失败时重新启动。 Not the most efficient solution but it would work. 不是最有效的解决方案,但它会起作用。 I wrote an untested version of this below. 我在下面编写了未经测试的版本。 May not run without errors but you should get the basic idea from it. 可能不会没有错误地运行,但是您应该从中获得基本思路。

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;
}

Try this code: 试试这个代码:

<?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>";
}
?>

Good luck! 祝好运!

Edit: Removed the call to srand() and commented-out the "if($i >= 2)" code, which is impossible anyway, here. 编辑:删除了对srand()的调用,并注释掉了“ if($ i> = 2)”代码,无论如何这是不可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM