我正在尝试创建一个随机字符串,用作短引用号。我花了最近几天试图让它工作,但它似乎达到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服务器并且没有重复。
在我们的环境中可能会导致这种行为?
答案 0 :(得分:0)
代码对我来说过于复杂。让我们假设你真的想要创建 n 唯一的字符串,每个字符串都基于一个随机值(rand / mt_rand / INT_MIN,INT_MAX之间的东西)。
您可以从编码中解耦随机值的生成开始(代码中似乎没有任何东西使字符串依赖于任何先前的状态 - 对唯一性的感知)。比较整数比比较任意字符串要快得多
mt_rand()返回INT_MIN和INT_MAX之间的任何内容,使用32位整数(也可能是64位,取决于如何编译php),它提供~2 32 元素。你想选择200k,让它成为400k,这是价值范围的1/10000。因此,假设一切都与唯一性相符合理是合理的......然后再检查一下。如果发生碰撞,请添加更多值。再次比在循环的每次迭代中检查in_array要快得多
一旦有足够的值,就可以将它们编码/转换为您想要的格式。我不知道<digit><character>-<something>
格式是强制性的,但假设它不是 - &gt; 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];
打印例如我的i7-4770 400000 400000 3.3981630802155 f3plox
。 ($end-$start
部分始终在3.2和3.4之间)
使用base_convert(),可以成为li10
之类的字符串,如果你必须手动输入字符串,解密就会非常烦人。