php函数生成随机字符串连续返回重复值

时间:2014-02-12 19:23:39

标签: php mysql random

我编写了一个函数来生成一个包含7个字母数字字符的随机字符串,然后将其插入到mysql数据库中。

以下是代码:

function getRandomID(){
   $tmp ="";
   $characters=array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9");
   for($i=0;$i<7;$i++) 
       $tmp.=$characters[rand(0,count($characters)-1)];
   return $tmp;
}

我没有检查重复项atm,因为我预计数据库中的条目不会超过1000个,并且我已经计算出这个函数可以返回(35)^ 7 = 64,339,296,875个可能的值。

我正在本地和现场服务器上测试它。

问题出在最后一小时,这个函数生成了两次重复值。

我在数据库中找到了3个条目,所有条目都有相同的随机字符串。

我不知道是什么导致这种情况,因为我之后尝试了很多次而且问题不可重现。

有没有人知道这里会发生什么?

非常感谢提前

4 个答案:

答案 0 :(得分:1)

使用“meh,这不会发生”的思维模式设计你的代码是一个非常冒险的游戏,只需正确执行一次,这样你就不必多次回到你的代码来快速修复小事情喜欢这些。

重复检查,你会坚实。

您可以创建类似

的功能
function stringExists($string)
{
     ...
    return $boolValue;
}

您可以轻松创建一个while循环,在生成旧字符串时生成新字符串。

$duplicate = true;
while($duplicate)
{
    $newString = getRandomId();
    $duplicate = !stringExists($string);
}
// Work with the newest string that is not a duplicate.

如果你真的想进入它

如果您想了解可能导致问题的原因,您可以查看兰特的documentation。此外,如果我们不知道有多少条目,则3个条目没有任何意义。有时“随机”功能并不像人们想象的那样随机,有时候某些编程语言中的随机函数总是可用的,但在它们变得“真正”随机之前需要某种启动。

插入的时间也可能是问题的一部分,互联网上有很多线程,比如堆栈溢出中的this,它有一些可能影响你的“随机”的有趣点。

无论是否真实,未在评论中指出,您可以非常肯定在相关主题和主题中找到问题的答案。

简短回答:不要考虑并重复检查,这很容易。

请注意,您当然应该首先使您的ID成为数据库中的UNIQUE约束。

答案 1 :(得分:0)

  1. 随机!=唯一。碰撞发生了。在插入数据库之前检查该值是否唯一,和/或在数据库中放置完整性约束以强制实现唯一性。
  2. 如果您使用的是非常旧版本的PHP [例如。在4.2之前]你必须使用srand()为随机数生成器播种。
  3. 除了#2之外,它可能不是您的getRandomID()函数,而是代码中的其他内容正在重复使用以前的值。

答案 2 :(得分:0)

如果需要在数据库中输入唯一数据,可以使用PHP函数uniqid()。 (http://ca3.php.net/uniqid

该函数根据当前的微秒生成更多的随机字符串。所以理论上它是独一无二的。

但是,在插入之前检查总是很好。或者至少在该字段上添加UNIQUE索引。

答案 3 :(得分:0)

你可以这样做:

function randomString($length, $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
    $string = "";
    $charsLength = strlen($chars);
    for ($i = 0; $i < intval($length); $i++) {
        $string .= $chars[rand(0, $charsLength - 1)];
    }
    return $string;
}

上面的函数将从给定的字符生成给定长度的随机字符串。这使得它比您的实现更灵活,如果您需要在以后的其他环境中使用它。

然后你可以做这样的检查:

$id = null;
do {
    $id = randomString(7);
} while (!isUnique($id));

// do your insert here. You need to write your isUnique, so that it checks if
// the given string is unique or not.