0

我需要创建固定长度的唯一且随机的字母数字 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 并且计数器重置,并永远继续这种模式。

有没有人知道任何适合这种需要的散列函数,或者有任何其他想法?

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

4

3 回答 3

1

正如您所意识到的,最困难的部分是确保确保无冲突序列。

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

本演示文稿以非常简洁的形式涵盖了 MCRNG 的基础知识和完整周期的充分条件。还有很多其他的。

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

您将需要“步进”模数以确保唯一性。例如,如果您的第一个 ID 是 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-12T17:48:53.173 回答
1

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

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

需要ID时,从unit 1-10中随机选择,获取unit的最新ID。例如,一开始,你的计数器是 1,随机选择是 unit-2,然后你会得到 ID=1001;第二次,你的计数器是 2,随机选择是 unit-1,你会得到 ID=1;第三次,你的计数器是3,随机选择是unit-2,你会得到ID=1002;...等等。

于 2013-07-12T18:16:40.603 回答
0

(这是不久前,但我应该写下我最终做了什么......)

我想出的想法其实很简单。我想要字母数字大头针,这样每个字符可以有 36 个潜在字符,我想从 4 个字符大头针开始,这样可以得到 36^4 = 1,679,616 个可能的大头针。我意识到我想做的就是拿走所有这些可能的别针,并以随机的方式扔掉其中的一部分,这样人类随机找到一个的机会就很小。所以我将 1,679,616 除以 100,然后将计数器乘以 1 到 100 之间的随机数,然后将该数字编码为我的字母数字密码。问题解决了!

通过猜测 4 个字母和数字的随机组合,你有 100 分之一的机会真正猜到一个真正使用中的别针,这正是我真正想要的。在我的实现中,一旦可用引脚空间用尽,我就会增加引脚长度,并且一切正常!跑了快2年了!

于 2015-12-08T00:14:43.753 回答