我想创建一个带有public_id的用户帐户,该用户帐户始终是唯一的整数随机(非增量)值。
我可以使用循环来检查随机整数是否是唯一的,但这似乎不是一个非常好的解决方案。
我发现了一些字母数字生成器,我想我可以使用一些字符串到整数转换器将它们转换为整数,但是有一种特定于整数的方法吗?
我也担心可能会发生碰撞,但看起来机会总会在那里长期存在。(?)
答案 0 :(得分:0)
您可以使用本地php函数之一,如mt_rand,也可以使用更可靠的方式 - 根据microtime函数生成整数。
要确保该值是唯一的,请在DB中的列上添加唯一索引,并写入“ON DUPLICATE UPDATE”查询,如果该值不唯一,将为该值添加一些数字
答案 1 :(得分:0)
有两种可能的解决方案:
1)如果你的“长跑”真的很长 - 这意味着这是 可能,你没有PHP_INT_MAX,没有 只有整数特定的方式。
2)如果你没有超出PHP_INT_MAX - 那么你需要一些存储空间 检查ids。
如果是1,您可以使用库hashids。为避免冲突 - 您需要输入一些增量计数器。然后你可以将每个字母的字符串转换回整数。
如果是2 - 您可以使用一些内存数据库(如redis)来提高性能。
答案 2 :(得分:0)
使用timeStamp真的会做得很好,因为它使用时间生成随机数。你也可以将下面的函数与其他随机生成的数字连接起来。
function passkey($format = 'u', $utimestamp = null){
if (is_null($utimestamp)) {
$utimestamp = microtime(true);
}
$timestamp = floor($utimestamp);
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format),$timestamp);
}
echo passkey(); // 728362
答案 3 :(得分:0)
您可以使用期限较长的linear congruential generator。
这是一个生成唯一的整数,总是有6位数。在生成100000和996722之间的所有数字之前,它不会生成重复项,这会为您提供近90万个不同的数字。
条件是您可以为函数提供上次生成的数字。因此,如果您将数字存储在数据库中,则必须以某种方式检索最后分配的数字,以便将其提供给此函数:
function random_id($prev) {
return 100000 + (($prev-100000)*97 + 356563) % 896723;
}
$prev = 100000; // must be a 6 digit number: the initial seed.
// Generate the first 10 pseudo-random integers.
for ($i = 0; $i < 10; $i++) {
$prev = random_id($prev);
echo $prev . "\n";
}
前10个数字的上一代产生:
456563
967700
331501
494085
123719
963860
855744
232445
749606
697735
您可以按照引用文章中有关在线性同余生成器中获取完整句点的规则,对其他范围执行此操作。具体地说,如果你想用 n 数字生成数字,那么第一个数字不能为零(所以在10 n-1 和10 n 之间-1),然后我发现在9⋅10 n-1 之下找到一个大的素数最容易作为公式的最后一个数。其他两个数字则可以是任何正整数,但最好保持第一个小以避免溢出。
但是,PHP整数限制为PHP_INT_MAX
(通常为2147483647),因此对于10位或更多位数的数字,您需要使用浮点运算符。那时不应该使用%
运算符。请改用fmod
。
例如,要生成12位数字,您可以使用以下公式:
function random_id($prev) {
return 100000000000 + fmod((($prev-100000000000)*97 + 344980016453), 899999999981);
}
$prev = 100000000000; // must be a 12 digit number: the initial seed.
// Generate the first 10 pseudo-random integers.
for ($i = 0; $i < 10; $i++) {
$prev = random_id($prev);
echo $prev . "\n";
}