可能重复:
生成随机数的算法
是否有可能生成一个从不重复的随机数??
php中有解决方案吗?还是codeIgniter?
例如,如果我需要为每个用户生成一个从不重复的随机id,我怎么能确保没有用户会有相同的id?
使用此选项:http://php.net/manual/en/function.uniqid.php
<?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));
?>
您需要多少这样的数字?如果你需要无限数量的唯一数字,你可能也需要无限空间来存储这样的数字。
如果你只想要一个特定范围内的数字,比如0到20亿,你可以确保你只使用这些数字中的每一个一次,方法是存储整个范围并对其进行洗牌。然后,每次你需要一个数字时,增加你上次使用的索引,以获得下一个数字。当达到最高索引时,生成一个新的范围,或者只重复使用相同的范围。
这个解决方案只会为20亿个数字花费8GB的数据,并且相互之间必须是唯一的。
但是,正如你所能想象的,通常有更好的解决方案,也许你可以使用一个不那么唯一的数字、时间戳,甚至只是一个递增计数器。
如果您将用户存储在数据库中,则可以使数据库为您生成一个唯一的userid。这将是一个不断递增的整数。如果您使用auto_increment int字段,那么您不会很快达到userid的限制。
如何确保没有用户拥有相同的id?
检查某些用户是否已经拥有它?
你的问题的简单答案是明确的否。如果它必须是完全随机的,那么就100%的概率而言,它永远不会是唯一的。
您可以生成长而复杂的随机令牌,并承担较小的非唯一性风险,也可以在生成后在数据库中检查唯一性。
但正如其他人所指出的,你很可能只是在要求解决一个已经解决的问题。这意味着您应该在数据库表中使用自动递增的主索引,以确保记录的唯一性。
要使某个东西变得唯一,您基本上需要一个唯一的字符串,以一个来自数据库甚至microtime(true)
的自动递增值开始,也许,如果你用用户名或电子邮件之类的东西检查唯一性,那么如果你没有来自数据库的自动递增值,就使用它。
这里有一个快速的usless函数,它将把字符串扩展成一个更唯一的值sha1,然后得到sha1字符串的crc校验和。并将其垫到最大len这有点过头了,因为你可以用000001000002来填补价值,但这其中的乐趣在哪里。
<?php
function make_user_id($id,$lenth=10){
return str_pad(substr(sprintf("%u", crc32(sha1($id))),0,$lenth), $lenth, "0", STR_PAD_LEFT);
}
//mysql_insert_id() or something unique from user, pahaps an email address or name
//example
foreach(range(1,25) as $id){
$array[]=make_user_id($id,10);
}
sort($array);
print_r($array);
/*
Array
(
[0] => 0299258281
[1] => 0361369892
[2] => 0391093287
[3] => 0422444891
[4] => 0492247561
[5] => 0642853861
[6] => 0737524653
[7] => 0860628658
[8] => 0944014851
[9] => 1054358011
[10] => 1065666469
[11] => 1194536188
[12] => 1390882148
[13] => 1617647885
[14] => 1648921238
[15] => 2611355852
[16] => 2612669788
[17] => 2615382585
[18] => 3526511484
[19] => 3578384747
[20] => 3888148475
[21] => 4095122425
[22] => 4197940240
[23] => 4288076077
[24] => 4293497861
)*/
?>
显然,数字总是有机会的,因为每个表单通常都是由相同的算法生成的。
最安全的方法是检查你的数据库,以确保,如果一个id已经采取了类似:
$id = "1"; //Your id to check
$query = "SELECT * FROM table where id=?";
$result = mysql_query($query);
if(mysql_num_rows($result)) {
//the id is present
}
如果你用mysqli代替会更好
$id = "1"; //Your id to check
$query = "SELECT * FROM table where id=?";
$stmt = mysqli_prepare($link, $query);
mysqli_stmt_bind_param($stmt, "i", $id);
mysql_stmt_execute($stmt);
if(mysql_stmt_num_rows($stmt))
//the id is present
}
mysqli_stmt_close($stmt);
bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM))
它将生成一个包含数字和字母的随机字符串(我将其用于密码盐)。从…起http://crackstation.net/hashing-security.html请阅读它是有帮助的。