指定长度唯一ID生成

时间:2013-07-12 16:43:28

标签: hash

我需要创建一组设定长度的唯一且随机的字母数字ID。理想情况下,我会在我的数据库中存储一个从0开始的计数器,每次我需要一个唯一的ID时,我会得到计数器值(0),通过这个散列函数运行它给它一个设定的长度(可能是4-6个字符)[ ID = Hash(Counter,4);],它会返回我的新ID(例如7HU9),然后我会增加我的计数器(0 ++ = 1)。

我需要保持ID的简短,以便可以轻松记住或分享。安全性不是一个大问题,所以我不担心人们尝试随机ID,但我不希望ID是可预测的,所以用户没有机会注意到ID的增量3每次允许他们通过ID向后工作并逐个下载ID数据(例如A5F9,A5F6,A5F3,A5F0 == BAD)。

我不想只是循环检查随机字符串的唯一性,因为随着密钥用完,这会增加数据库负载。目的是散列一个唯一的递增计数器将保证ID唯一性达到某个计数器值,此时生成的ID的长度将增加1并重置计数器,并永远继续这种模式。

是否有人知道任何适合此需求的散列函数,或者有任何其他想法?

编辑:我不需要能够反转该函数来获取计数器值。

3 个答案:

答案 0 :(得分:1)

正如您所意识到的那样,困难的部分是保证无碰撞顺序。

如果“不明显”是您猜测算法所需的标准,那么整个周期的简单混合同余RNG - 或者更确切地说是一系列具有增加的模数以满足随时间增长的要求 - 可能是您想要的。这不是你要求的哈希方法,但它应该工作。

This presentation以非常简洁的形式涵盖了MCRNG的基础知识和完整时期的充分条件。还有很多其他的。

你首先使用从任意种子开始的最低模量MCRNG,直到你“用完”它的周期,然后进入下一个最大模数。

您需要“步进”模数以确保唯一性。例如,如果您的第一个ID是12位,因此您的模数M1 <= 2 ^ 12(但不会小于),那么您前进到16位,您需要选择第二个模数M2&lt; = 2 ^ 16 - M1。所以id的第二层是M1 + x_i,其中x_i是第二个rng的第i个输出。 32位第三层的模数为2 ^ 32-M2,其输出为M2 + y_i,其中y_i为其输出等。

所需的唯一持久存储将是生成的最后一个ID和序列中MCRNG的索引。

有时间在他们手上的人可以毫不费力地猜测这个算法。但是一个随意的用户不太可能这样做。

答案 1 :(得分:1)

假设您的计数器范围从1到10000.切片[1,10000]到10个小单位,每个单位包含1000个数字。这个小单位将跟踪他们的最后一个ID。

 unit-1    unit-2              unit-10
[1 1000], [1001, 2000], ... ,[9000, 10000]

当您需要ID时,只需从1-10单元中随机选择,即可获得该单元的最新ID。 例如 首先,你的计数器是1,随机选择是单位-2,你得到的ID = 1001; 第二次,你的计数器是2,随机选择是单位-1,比你得到的ID = 1; 第三次,你的计数器是3,随机选择是单位-2,比你得到的ID = 1002; ......等等。

答案 2 :(得分:0)

(这是前一段时间,但我应该写下我最终做的事情......)

我提出的想法实际上非常简单。我想要字母数字引脚,因此每个字符可以使用36个潜在字符,我想从4个字符引脚开始,这样就可以得到36 ^ 4 = 1,679,616个可能的引脚。我意识到,我想做的就是把所有这些可能的引脚扔掉,然后以随机的方式丢掉一部分它们,这样人类就有机会随机找到一个。所以我将1,679,616除以100,然后将我的计数器乘以1到100之间的随机数,然后将该数字编码为我的字母数字引脚。问题解决了!

通过猜测4个字母和数字的随机组合,您实际猜测真正使用中的引脚的概率是百分之一,这是我真正想要的。在我的实现中,一旦可用的引脚空间耗尽,我就增加引脚长度,一切都完美无缺!已经运行了大约2年了!