我需要创建唯一的和随机的字母数字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并且计数器复位,并且永远继续该模式。
有没有人知道可以满足这种需求的散列函数,或者有其他想法?
编辑:我不需要能够反转函数来获得计数器值。
发布于 2015-12-08 08:14:44
(这是一段时间之前的事情,但我应该写下我最终做了什么……)
我的想法其实很简单。我想要字母数字引脚,所以每个字符有36个可能的字符,我想从4个字符引脚开始,这样就得出36^4 = 1,679,616个可能的引脚。我意识到,我所要做的就是拿出所有这些可能的引脚,并以随机的方式丢弃其中的一部分,这样人类就有很低的机会随机找到一个。所以我将1,679,616除以100,然后将我的计数器乘以1到100之间的一个随机数,然后将该数字编码为我的字母数字pin。问题解决了!
通过猜测4个字母和数字的随机组合,您有1/ 100的机会实际猜测一个真正的正在使用的引脚,这是我真正想要的。在我的实现中,一旦可用管脚空间耗尽,我就增加管脚长度,一切都正常工作!已经运行了大约2年了!
发布于 2013-07-13 01:48:53
正如您所意识到的,最困难的部分是获得无冲突序列保证。
如果“不明显”是您猜测算法所需的标准,那么完整周期的简单混合同余RNG -或者更确切地说,是一系列具有递增模数以满足随时间增长的需求的RNG-可能是您想要的。这不是您所要求的散列方法,但它应该可以工作。
This presentation以非常简洁的形式涵盖了MCRNG的基础知识和完整周期的充分条件。还有很多其他的。
首先使用最低模数MCRNG,从任意种子开始,直到“用完”它的周期,然后前进到下一个最大模数。
您将希望“步进”模块以确保唯一性。例如,如果您的第一个‘d是12位,因此您的模数M1 <=为2^12 (但不会太小),那么您将前进到16位,您可能希望选择第二个模数M2 <= 2^16 - M1。因此,第二层id应该是M1+x_i,其中x_i是第二个rng的第i个输出。32位第三层的模数为2^32-M2,其输出为M2+y_i,其中y_i是其输出,依此类推。
唯一需要的持久存储是序列中最后生成的ID和MCRNG的索引。
手头有时间的人可以毫不费力地猜出这个算法。但普通用户不太可能这样做。
发布于 2013-07-13 02:16:41
假设您的计数器范围是从1到10000。片1,10000到10个小单元,每个单元包含10000个number.These小单元将跟踪它们最后一个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;...and等等。
https://stackoverflow.com/questions/17619858
复制相似问题