我正在尝试创建一个随机字符串,用作短引用号。在过去的几天里,我一直在努力让它发挥作用,但它似乎达到了大约 32766 条记录,然后它继续无休止地重复。我至少需要 200,000 个变体。
下面的代码是一个非常简单的模型,用于解释会发生什么。代码的语法应根据 1a-x1y2z(示例)给出比 32k 更多的结果
我感觉这可能与内存有关但不确定。有什么想法吗?
<?php
function createReference() {
$num = rand(1, 9);
$alpha = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, 1);
$char = '0123456789abcdefghijklmnopqrstuvwxyz';
$charLength = strlen($char);
$rand = '';
for ($i = 0; $i < 6; $i++) {
$rand .= $char[rand(0, $charLength - 1)];
}
return $num . $alpha . "-" . $rand;
}
$codes = [];
for ($i = 1; $i <= 200000; $i++) {
$code = createReference();
while (in_array($code, $codes) == true) {
echo 'Duplicate: ' . $code . '<br />';
$code = createReference();
}
$codes[] = $code;
echo $i . ": " . $code . "<br />";
}
exit;
?>
更新
所以我开始怀疑这是否与我们的 WAMP 设置 (Bitnami) 不符,因为我们的本地机器在开始复制之前正好达到 1024 条记录。通过从上面的字符串中删除 1 个字符(而不是 for 循环中的 6 个字符,我将其设为 5),它正好达到 32768 条记录。
我把脚本上传到我们的centos服务器,没有重复。
在我们的环境中,什么会导致这种行为?
最佳答案
代码在我看来过于复杂。让我们暂时假设您真的想创建 n 个独特的字符串,每个字符串都基于单个随机值(rand/mt_rand/介于 INT_MIN、INT_MAX 之间的某个值)。
您可以首先将随机值的生成与编码解耦(代码中似乎没有任何内容使字符串依赖于任何先前的状态——唯一性除外)。比较整数比比较任意字符串快很多。
mt_rand() 返回 INT_MIN 和 INT_MAX 之间的任何值,使用 32 位整数(也可以是 64 位,取决于 php 的编译方式),给出 ~232 元素。您想选择 200k,让我们将其设为 400k,即值范围的 1/10000。因此,可以合理地假设一切都与唯一性相得益彰……然后稍后再检查。并在发生碰撞时添加更多值。同样比在循环的每次迭代中检查 in_array 快得多。
一旦你有足够的值,你就可以将它们编码/转换成你想要的格式。我不知道 <digit><character>-<something>
是否格式是强制性的,但假设它不是 -> base_convert()
<?php
function unqiueRandomValues($n) {
$values = array();
while( count($values) < $n ) {
for($i=count($values);$i<$n; $i++) {
$values[] = mt_rand();
}
$values = array_unique($values);
}
return $values;
}
function createReferences($n) {
return array_map(
function($e) {
return base_convert($e, 10, 36);
},
unqiueRandomValues($n)
);
}
$start = microtime(true);
$references = createReferences(400000);
$end = microtime(true);
echo count($references), ' ', count(array_unique($references)), ' ', $end-$start, ' ', $references[0];
打印例如400000 400000 3.3981630802155 f3plox
在我的 i7-4770 上。 ($end-$start
部分一直在3.2和3.4之间)
使用 base_convert() 可以是像 li10
这样的字符串,如果您必须手动输入字符串,那么破译起来会很烦人。
关于php - 随机生成器返回无限重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35795891/