Random 将数字序列转换为随机外观ID?

Random 将数字序列转换为随机外观ID?,random,Random,我正在开发一个需要生成唯一、非顺序ID的应用程序。我的一个限制是,它们必须由3位数字和2个字母组成,大约只有600k ID。考虑到我的ID池相对较小,我正在考虑简单地生成所有可能的ID,将它们洗牌并放入数据库。因为,在内部,我将有一个简单的、连续的ID来使用,所以一次只取一个就很容易了&确保我没有任何重复 这感觉不是一个非常令人满意的解决方案。是否有人有比这种“抽奖”方法更有趣的从有限的池中生成唯一ID的方法?根据您定义的顺序,您可以选择字母的某个起始点,例如“aa”,然后在三个数字之间循环,因

我正在开发一个需要生成唯一、非顺序ID的应用程序。我的一个限制是,它们必须由3位数字和2个字母组成,大约只有600k ID。考虑到我的ID池相对较小,我正在考虑简单地生成所有可能的ID,将它们洗牌并放入数据库。因为,在内部,我将有一个简单的、连续的ID来使用,所以一次只取一个就很容易了&确保我没有任何重复


这感觉不是一个非常令人满意的解决方案。是否有人有比这种“抽奖”方法更有趣的从有限的池中生成唯一ID的方法?

根据您定义的顺序,您可以选择字母的某个起始点,例如“aa”,然后在三个数字之间循环,因此: 001aa 002aa 003aa


到达zz后,增加数字部分。

您可以生成一个符合该标准的随机ID,进行DB选择以查看它是否已经存在,然后将其插入DB以说明它已被使用。对于该方案生命周期的前25%或大约150k个条目,生成新的随机ID应该相对较快。但是,在这之后,它将花费越来越长的时间,您也可以预先填充表格以查找免费ID。

使用有限组。基本上,取一个32位或64位整数,并找到一个与整数的最大值互质的大数字;调用这个数字M。然后,对于所有整数n,n*M将产生一个具有许多数字的唯一数字


这样做的好处是,您不需要预先填充数据库,也不需要运行单独的select查询—您可以在一条insert语句中完成这一切,方法是使n只是一个自动递增,并且有一个单独的ID列,默认为n*M。

这可以通过许多不同的方式完成,取决于您试图优化的速度、内存使用等

ID模式=ddd cc[0]

选项1本质上类似于散列,类似于Zak的: 1生成一个介于0和可能数676k之间的随机数。 2-将数字转换为组合

3-查询数据库是否存在ID和增量,直到找到一个空闲的ID和增量

选项2线性反馈移位寄存器,参见: 1-随机数范围为0676K的种子。请参见下面无法使用“0”进行种子设定的原因 2-通过对当前ID号应用以下内容生成后续随机数

3-跳过大于范围ie 0xA50A0的ID+ 4-如上所述将数字转换为ID格式 *您将需要保存生成的用于ID的最后一个数字,但不需要查询DB以查看是否使用了它。由于LFSR的工作方式,此解决方案将枚举除[000 AA]之外的所有可能ID


[编辑]由于您的范围实际上大于您需要的范围,因此在转换为ID之前,您可以通过减去1获得[000 AA],并使您的有效范围为0,0xA50A0]

您可以使用模块化算法生成ID。选择一个与676000和为种子的互质数。id是表的标准递增id。那么您需要以下伪代码:

uidNo = (id * seed) % 676000
digits = uidNo / 676
char1 = uidNo % 26
char2 = (uidNo / 26) % 26
uidCode = str(digits) + chr(char1+65) + chr(char2+65)

如果用户有多个连续发布的id,他们可以猜测算法和种子并按顺序生成所有id。这可能意味着该算法对于您的用例来说不够安全。

您计划实际使用多少ID?生成这么多并存储它们(例如,仅使用几百个)会很遗憾。为什么它们是顺序的呢?您可以将其封装在返回未使用id的存储过程中。这样,您就不会在实际测试id时重复敲打数据库,如果你看到这两个ID并排出现,或者在任何距离看到任何3个或更多个ID,你就能够得到你看到的ID的gcd,并且能够准确地预测下一个ID。不幸的是,这个解决方案的熵很小。而且,这不符合OP使用的3位2字母规格,我很好奇。LFSR算法从何而来?
    num = (num >> 1) ^ (-(num & 1u) & 0x90000u);
uidNo = (id * seed) % 676000
digits = uidNo / 676
char1 = uidNo % 26
char2 = (uidNo / 26) % 26
uidCode = str(digits) + chr(char1+65) + chr(char2+65)