我需要生成符合以下要求的字符串:
我会在生成后将它们存储在数据库中(它们将被分配给其他实体)。
我的意图是做这样的事情:
我对该算法的关注是它不能保证有限时间内的结果(如果数据库中已有很多值)。
问题:请您就如何改进此算法提供更具确定性的建议?
感谢。
答案 0 :(得分:6)
- 它应该是唯一的字符串;
- 字符串长度应为8个字符;
- 它应包含2位数字;
- 所有符号(非数字字符) - 应为大写。
醇>
假设:
然后您提出的方法有两个问题。一个是字母A - Z是ASCII 65 - 90,而不是64 - 89.另一个是它不会在可能的字符串空间内均匀分布数字。这可以通过执行以下操作来解决:
两种不同的整数有两种可能性((8 * 8 - 8次重复)/ 2次排序),26种 6 可能的字母,100种可能的数字,总数#有效组合为N comb = 864964172800 = 8.64 x 10 11 。
编辑:如果您想避免数据库存储,但仍然保证字符串和的唯一性使它们具有加密安全性,那么您最好的选择是加密随机从0和N max < = N comb 之间的计数器的双射到可能输出串的空间的子集。 (Bijection表示输出字符串和输入计数器之间存在一对一的对应关系。)
Feistel networks可以实现这一点,它们通常用于散列函数和对称加密(包括AES)。您可能希望选择N max = 2 39 ,这是2< = N comb 的最大功率,并使用39 -bit Feistel网络,使用您保密的常量密钥。然后将计数器插入Feistel网络,然后输出另一个39位数字X,然后将其转换为相应的字符串,如下所示:
或者,使用40位数字,如果您的Feistel网络的输出是> N comb ,然后递增计数器并再试一次。这将覆盖整个字符串空间,代价是拒绝无效数字并且必须重新执行算法。 (但是您不需要数据库来执行此操作。)
但除非你知道自己在做什么,否则这不是什么。
答案 1 :(得分:2)
这些用户密码是?如果是这样,您需要考虑以下几点:
就2而言,您可以通过使用LLNLLNLL作为模式来避免此问题(L =字母,N =数字)。
如果您需要一个25亿个池中的100万个密码,您肯定会在数据库中发生冲突,因此您必须优雅地处理它们。但是,如果您的随机数生成器很稳健,那么简单的重试就足够了。
答案 2 :(得分:0)
我没有在您的要求中看到任何声明该字符串必须是随机的。您可以执行以下伪代码:
for letters in ( 'AAAAAA' .. 'ZZZZZZ' ) {
for numbers in ( 00 .. 99 ) {
string = letters + numbers
}
}
这将创建八个字符长的唯一字符串,两个数字和六个大写字母。
如果你需要随机生成的字符串,那么你需要保留一些先前生成过哪些字符串的记录,这样你就不得不点击一个数据库(或者将它们全部留在内存中,或者写出来到文本文件)并检查该列表。
答案 3 :(得分:0)
我认为你对成千上万的这类ID很安全,甚至在那之后你很可能还好。
现在,如果你想要一些确定性,你可以在一定数量的失败后强制输入密码。在50次失败后说,你随机选择一个密码并将其中的一部分增加1,直到获得一个免费密码。
我愿意打赌,虽然你在生活中永远不会看到额外的功能:)
答案 4 :(得分:0)
首先,您的需求列表并未声明字符串必须是随机的,因此您可能会考虑类似数据库索引。
如果要求“随机”,您可以做一些改进。
例如,如果我们有序列1,2,3,4 ......并且使用循环二进制右移1位,它将变为4,1,5,2 ......(假设我们只有3位) 它也不一定是一种转变,它可以是一种排列或任何其他“随机化”。
答案 5 :(得分:0)
反过来说:生成一个大的随机数,你将拆分以获得单个字符:
long bigrandom = ...;
int firstDigit = bigRandom % 10;
int secondDigit = ( bigrandom / 10 ) % 10;
等等。
然后,您只将随机数存储在数据库中,而不是字符串。由于字符串和数字之间存在一对一的关系,因此这并没有什么区别。
但是,当您尝试插入新值并且它已经在数据库中时,您可以轻松找到最小的未分配数字,而不是最初生成的数字,并使用它而不是您生成的数字。
您从这种方法中获得的是,即使已经分配了大部分代码,您仍可以相对快速地找到可用代码。
答案 6 :(得分:0)
你的方法的问题很明显,虽然你的记录很少,但你不太可能发生碰撞,但随着记录数量的增加,机会会增加,直到你发生碰撞的可能性增大。最终,在获得“有效”结果之前,您将遇到多次碰撞。每次都需要进行表扫描以确定代码是否有效,并且整个过程变得一团糟。
最简单的解决方案是预先计算您的代码。
从第一个代码00AAAA开始,然后递增以生成00AAAB,00AAAC ... 99ZZZZ。以随机顺序将它们插入表中。当您需要新代码时,从表中检索到顶部记录未使用的记录(然后将其标记为已使用)。如上所述,它不是一张巨大的表 - 只有几百万条记录。
如果您需要更多“代码”,只需生成一些“随机”字符串并将其附加到表格中。