【问题标题】:how to generate unique random numbers in php?如何在php中生成唯一的随机数?
【发布时间】:2018-04-10 03:36:18
【问题描述】:

我正在使用 php random 函数生成随机数,但我希望生成的数字应该是唯一的,并且不应该再次重复。

----------
php code
 $number = rand(100,100000); //a six digit random number between 100 to 100000 
echo $number;

----------

但是我在我的代码中为用户多次使用这个函数,所以在极少数情况下应该有机会再次生成相同的数字。我怎样才能避免这种情况。

【问题讨论】:

  • 店铺号,查看之前是否使用过。只有 100% 可靠的随机数方式
  • 这是干什么用的?
  • 为客户制作唯一 ID
  • 您是否将其存储在数据库中?你也可以使用你的主键
  • 最好的方法是 - 1. 使用rand() 生成随机数。 2. 获取当前时间戳。 3. 添加一个prefix,它可能是一个字符串,具体取决于您的业务逻辑。 4.将这三者结合起来,得到一个随机的唯一编号!此过程可确保更高的准确性,不会获得相同的数字。

标签: php


【解决方案1】:

我会这样做:

你说你有分支。收据 ID 可能如下所示:

$dateString = date('Ymd'); //Generate a datestring.
$branchNumber = 101; //Get the branch number somehow.
$receiptNumber = 1;  //You will query the last receipt in your database 
//and get the last $receiptNumber for that branch and add 1 to it.;

if($receiptNumber < 9999) {

  $receiptNumber = $receiptNumber + 1;

}else{
 $receiptNumber = 1;
} 

使用收据编号更新收据数据库。

$dateString . '-' . $branchNumber . '-' . $receiptNumber;

这将显示:

20180406-101-1 

这将是独一无二的(前提是您每天进行的交易少于 10,000 笔。)并将向您的员工展示易于阅读的信息。

【讨论】:

  • 没问题!干杯
【解决方案2】:

如果您将用户存储在数据库中,您应该创建列 [ID] 作为具有自动增量的主键,这将是最好的解决方案。

在其他情况下,我建议您通过读取最后一个 ID 并向其添加 1,以从 N 到 M 的升序存储所有用户 ID,因为我认为随机顺序没有真正的收益,只会增加代码的复杂性。

【讨论】:

    【解决方案3】:

    random_int (PHP 7)

    <?php
    $number =  random_int(100, 100000);
    echo $number;
    

    【讨论】:

      【解决方案4】:

      你需要做的就是在php中使用时间戳,因为时间戳永远不会相互交叉,因此它总是会生成唯一的数字。你可以在php中使用time()函数。

      time() 函数用于将时间戳格式化为人类所需的格式。时间戳是当前时间与 1970 年 1 月 1 日 00:00:00 GMT 之间的秒数。它也称为 UNIX 时间戳。

      <?php
      $t=time();
      echo $t;
      ?>
      

      您还添加了一个rand() 函数并将其插入到$t 前面,以使其更加随机,就好像很少有用户同时工作那么时间戳可能会发生冲突。

      <?php
      $number = rand(100,100000);
      $t=time();
      $random = $number.''.$t;
      
      echo $random;
      ?>
      

      以上将减少时间戳碰撞的机会,从而使数字唯一性的概率几乎 100%。

      如果您在数据库中创建列unique,那么 php 将不会插入数字,因此这个瓶颈将确保您始终获得唯一的随机数。

       bill_id not null unique
      

      【讨论】:

      • 如果两个用户/进程同时工作,很有可能出现并发问题!
      • 是的 Erfan 你是对的,因此应该在下面添加另一个函数来检查数字是否等于最后 10 条记录,如果不等于则插入数字,否则使用延迟函数然后插入它.
      • Erfan ahmed 谢谢你和 adern 我怎样才能使延迟功能
      • 最近 10 条记录不是检查唯一性的理想阈值。此外,在插入之前每次检查也是一种开销和性能。最好在生成的列上使用 DB 中的唯一约束,例如 ran_unq_num not null unique。我已经对这些问题发表了评论。这应该足以让他想出一个答案!
      • 你能告诉我为什么需要随机数吗,因为我会根据你的回答编辑答案。
      【解决方案5】:

      方法有很多,例如:

      $freq = [];
      $number = rand(100,100000);
      $times = 10;
      while($times-- > 0)
      {
         while(in_array($number, $freq))$number = rand(100,100000);
         $freq[] = $number;
         echo $number . "<br>";
      }
      

      这将打印 10 个随机唯一数字。

      【讨论】:

        【解决方案6】:

        如果您将它用于用户 ID 之类的东西,那么您可以使用 uniqid。此命令会根据当前时间(以微秒为单位)获取带前缀的唯一标识符。

        使用方法如下:

        string uniqid ([ string $prefix = "" [, bool $more_entropy = FALSE]] )
        

        如果您同时为多个主机生成 id,则使用前缀,如果 id 在同一微秒内生成,您可以使用它来区分不同的主机。

        more_entropy 增加了获得唯一值的可能性。

        用法:

        <?php
        /* A uniqid, like: 4b3403665fea6 */
        printf("uniqid(): %s\r\n", uniqid());
        
        /* We can also prefix the uniqid, this the same as 
         * doing:
         *
         * $uniqid = $prefix . uniqid();
         * $uniqid = uniqid($prefix);
         */
        printf("uniqid('php_'): %s\r\n", uniqid('php_'));
        
        /* We can also activate the more_entropy parameter, which is 
         * required on some systems, like Cygwin. This makes uniqid()
         * produce a value like: 4b340550242239.64159797
         */
        printf("uniqid('', true): %s\r\n", uniqid('', true));
        ?>
        

        【讨论】:

          【解决方案7】:

          此代码必须有效

          关于代码的一些描述:

          1. 生成唯一标识
          2. 使用正则表达式从唯一 ID 中提取数字
          3. 使用循环从正则表达式中收集数字
          <?php
          
          $unique = uniqid("",true);
          preg_match_all("!\d+!", $unique ,$matches);
          print_r($matches);
          $numbers = "";
          foreach($matches[0] as $key => $num){
             $numbers .= $num; 
          }
          
          echo $numbers;
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-05
            • 2011-06-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多