因为它需要是唯一的,没有两个项目会有相同的信息,我可以使用哈希,但它需要是他们可以与其他人分享的代码-因此是7位数字。
我的最初想法只是循环生成一个随机数,检查它是否已经被使用,如果是,那么重复这个过程。考虑到碰撞的可能性较低,我认为这是一个合理但不太好的解决方案。 这个问题的回答建议生成所有未使用数字的列表并对其进行洗牌。我可能可以在数据库中保留这样的列表,但我们正在谈论的是相对不频繁的事情,需要1000万条目。
有没有更好的方法?
选择一个七位数的质数,称之为A,再选一个大的质数,称之为B,然后
int nth_unique_7_digit_code(int n) {
return (n * B) % A;
}
由此生成的所有唯一代码的数量将为A。
如果您想更加“安全”,可以执行pow(some_prime_number, n) % A
,即
static int current_code = B;
int get_next_unique_code() {
current_code = (B * current_code) % A;
return current_code;
}
您可以使用递增的ID,然后将其与一些固定密钥进行异或运算。
const int XORCode = 12345;
private int Encode(int id)
{
return id^XORCode;
}
private int Decode(int code)
{
return code^XORCode;
}
我建议使用GUID而不是7位数字代码,因为它更加唯一,您不必担心生成它们,因为.NET将为您完成此操作。
所有“唯一”ID的解决方案都必须在某个数据库中:其中一个包含已使用的ID,或者一个包含空闲ID的数据库。正如您所注意到的那样,带有空闲ID的数据库将非常庞大,因此大多数人使用“已使用的ID”数据库并检查冲突。
话虽如此,一些数据库提供了“随机ID”生成器/序列,它已经以随机顺序返回ID范围内的ID。
这是通过使用一个随机数生成器来创建一个范围内的所有数字,而不重复本身加上保存在某个地方其状态的特性来实现的。因此,您可以运行生成器一次,使用该ID并保存新状态。对于下一次运行,您加载状态并将生成器重置为最后状态以获取下一个随机ID。
我假设您将拥有一张“生成的”表。在这种情况下,我认为随机选取数字并检查它们是否与数据库匹配不是问题,但我不会逐个执行此操作。生成它们很便宜,与此相对,查询数据库是昂贵的。我会一次生成100或1,000个,然后询问数据库哪些存在。我打赌大部分时间您不必再做一遍。
我会尝试使用LFSR(线性反馈移位寄存器),代码非常简单,你可以在各处找到示例,例如Wikipedia,虽然它不是加密安全的,但看起来非常随机。此外,由于主要使用移位操作,实现速度也非常快。
如果数据库中只有数千个项目,您的原始想法似乎是正确的。在几万个项目的排序(索引)列表中检查值的存在只需要进行几次数据获取和比较。
预先生成列表听起来不是一个好主意,因为您要么会存储比必要更多的数字,要么就必须处理用完它们的情况。
具有命中的概率非常低。
例如 - 你有10^4个用户和10^7个可能的ID。
你连续十次选择已使用过的ID的概率现在是10^-30。
这个机会比任何人一生中都要低。
static int i=9999999;int get_non_increasing_unique_code(void){return i--;}
静态整型变量i被赋初值为9999999。调用get_non_increasing_unique_code函数将返回i的当前值,然后i减1。返回的值是一个不递增的独特代码(即每次调用都会产生唯一的代码)。 - kennytm