我有两个函数,makeKey() 和 keyExists()。
makeKey() 简单地生成一个 5 位随机字母数字密钥,keyExists() 接受这个密钥作为它的唯一参数,并在一个表中查找,根据它是否存在返回真/假。
我需要做一些非常简单的事情,但我想不出最快的方法。
我只需要创建一个键,如果它存在于表中,则再次创建一个键,依此类推,直到返回一个唯一的键。我认为一个while循环就足够了?
谢谢,请原谅这个相当基本的问题,我想我昨天在阳光下煮了我的大脑。
我有两个函数,makeKey() 和 keyExists()。
makeKey() 简单地生成一个 5 位随机字母数字密钥,keyExists() 接受这个密钥作为它的唯一参数,并在一个表中查找,根据它是否存在返回真/假。
我需要做一些非常简单的事情,但我想不出最快的方法。
我只需要创建一个键,如果它存在于表中,则再次创建一个键,依此类推,直到返回一个唯一的键。我认为一个while循环就足够了?
谢谢,请原谅这个相当基本的问题,我想我昨天在阳光下煮了我的大脑。
我会使用do
-while
循环:
do {
$newKey = makeKey();
} while (keyExists($newKey));
这将在每次迭代时生成一个新密钥,直到该密钥尚不存在。
任何依赖于创建然后检查的解决方案都会在关键空间被填满时表现出糟糕的表现。您最好使用自动生成的列(身份或 guid)生成唯一键。如果它需要是字母数字,请使用映射函数将其转换为您选择的字母表,方法是选择位组并将它们用作字母表的索引。
伪代码
alphabet = "ABCDE...789";
key = insert new row, get autogenerated key
alphaKey = "";
while (get n bits from key)
alphaKey += alphabet[bits]
done
echo alphaKey
我的 php 有点生锈,所以考虑一下这个伪代码:
$key_exists = true;
while($key_exists) {
$key = generateKey();
$key_exists = checkKey($myKeysHash, $key);
}
// $key is now unique and ready to use
为什么不使用像uniqid()这样的内置 php 函数?
您提到了一个表,所以我想知道您是否将这些键存储在数据库中?如果是这样,您的方法将有一个竞争条件 - 您可能会在另一个进程使用该密钥之前检查一个密钥是否可以使用。
更好的方法是生成一个可能的密钥,然后尝试将其持久化——也许通过对密钥表执行 INSERT 并使用不同的密钥重试直到成功。
如果您不固定在 5 位数字上,则可以考虑使用 id + name 列的哈希值。
我还将假设您正在使用某种数据库。
您不能在数据库中使用唯一的自增 ID 列吗?它将删除检查密钥是否存在的要求,因为数据库引擎永远不会两次分配相同的 ID。
但是,您必须更改应用程序中的逻辑,而不仅仅是编写新功能。
需要随机吗?只需增加一个变量并存储下一个以在另一个字段中使用。
while (keyExists($newKey = makeKey()));
可能是最快的检查方法,如果存在密钥,它将生成一个新密钥。如果您开始有很多冲突/需要在获取新的唯一密钥之前多次检查数据库,您可能需要重新考虑您的 makeKey() 算法。对数据库的调用很昂贵,调用越少,脚本就越快、越高效。