如何在数组中生成不存在的标识符?

How can I generate a nonexistent identifier in an array?

我想生成一个长度为 12 个字符的唯一值。要生成唯一值,我使用此方法:

function generate_unique_id()
{
    $time = substr(time(), -7);
    $month = mb_strtolower(date("M"));
    $symbol = "OM";
    $string = $month."".$time."".$symbol;
    $result = str_shuffle($string);
    return $result;
}

我测试了这段代码生成了 30,000 个唯一值,但是每次退出循环都没有生成所需的唯一标识符。

$array = [];

for($i=0; $i<=3; $i++)
{
    $unique_id = generate_unique_id();
    if(in_array($unique_id, $array)){
        echo $i;
        break;
    }
    $array[] = $unique_id;
}

在生成能力没有达到最大个数限制的情况下,如何知道生成的12个字符串唯一值的个数并快速生成唯一值

未经测试,但应该可以工作(随机前缀 + 十六进制计数器后缀):

<?php

function unique_id($length = 12)
{
    static $counter = 0;
    $suffix = dechex($counter);
    $prefixLen = $length - strlen($suffix);
    $prefix = substr(uniqid(), -$prefixLen);
    $counter++;
    return $prefix.$suffix;
}

$arr = array();
for ($i = 0; $i < 30000; $i++)
{
    $id = unique_id();
    if (in_array($id, $arr))
    {
        echo $id."\n";
        break;
    }
    $arr[]= $id;
}

echo "Generated ".count($arr)." unique IDs.\n";

请注意,这仅在您在 一个 请求/脚本执行中需要所有这些 ID 时才有效。新请求会导致静态 $counter 变量重新开始,这不再保证唯一 ID。

下面的代码在 21.3783249855041 秒内生成了 30,000 个唯一 ID。

$ids = [];

while (count($ids) < 30000) {
  $id = bin2hex(random_bytes(6));

  if (!in_array($id, $ids)) array_push($ids, $id);
}

var_dump(count($ids));
var_dump($ids);

上面的代码将继续生成 ID,直到获得 30,000 个唯一 ID,没有理由 break

1生成时间可能不同。

实例

Repl

更新#1

没有PHP 7的可以使用this函数。

更新#2

根据 @cckep 评论:

此代码段效率更高
$time_start = microtime(true); 
$ids = [];

while (count($ids) < 30000) {
  $id = bin2hex(random_bytes(6));

  if (!isset($ids[$id])) $ids[$id] = true;
}

$ids = array_keys($ids);

$time_end = microtime(true);
$execution_time = ($time_end - $time_start);

var_dump(count($ids));
var_dump($ids);

echo $execution_time;