如何生成唯一,较小,随机且用户友好的密钥?

时间:2020-03-05 18:45:04  来源:igfitidea点击:

几个月前,我的任务是为我们的Web应用程序实现唯一且随机的代码。该代码将必须是用户友好的并且尽可能小,但实际上仍然是随机的(因此用户无法轻易预测序列中的下一个代码)。

最终生成的值看起来像这样:

Af3nT5Xf2

不幸的是,我从未对实施感到满意。 Guid毫无疑问,它们太大了,用户难以输入。我希望能以4或者5个字符/数字的形式显示更多信息,但是如果我们编码为少于9个字符。

我们最终要做的是:

我们从数据库中提取了一个唯一的连续32位ID。然后,我们将其插入64位RANDOM整数的中心位。我们创建了一个查找表,其中包含易于键入和识别的字符(A-Z,a-z,2-9跳过容易混淆的字符,例如L,l,1、0、0等)。最后,我们使用该查询表以base-54编码64位整数。高位是随机的,低位是随机的,但中心位是顺序的。

最终结果是一个比guid小得多的代码,看起来是随机的,即使绝对不是。

我从未对这种特定的实现感到满意。你们会做什么?

解决方案

回答

在C#中,我使用了'System.IO.Path.GetRandomFileName():String'方法...但是我正在为调试文件名生成盐。此方法返回的内容类似于第一个示例,但文件扩展名也为随机的" .xyz"。

如果我们使用的是.NET,并且只想要一个更简单(但看起来不是"更")的解决方案,那么我就说这是...我们可以根据需要删除随机文件扩展名。

回答

在.NET中,我们可以使用RNGCryptoServiceProvider方法GetBytes(),该方法将"使用加密的强随机值序列填充字节数组"(来自ms文档)。

byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);

我们可以增加字节数组的长度,并选择要允许的字符值。

回答

这就是我的做法。

我将获得带有用法频率和一些语法信息的通用英语单词列表(例如名词还是动词?)。我认为我们可以环顾一下插管,以获取一些副本。 Firefox是开源的,并且具有拼写检查器...因此必须以某种方式可获得。

然后,我对其运行过滤器,以除去晦涩的单词,并排除太长的单词。

然后,我的生成算法将从列表中选择2个单词并将其连接起来,并添加一个随机的3位数字。

我也可以在动词/名词之间随机选择单词选择模式

eatCake778

  pickBasket524

  rideFlyer113
  etc..

不需要是驼峰的情况下,我们也可以将其随机化。我们也可以随机分配数字和动词/名词的位置。

而且由于有很多随机性,所以必须读杰夫(Jeff)的《娜格维特的危险》(The Danger of Na?vet)。另外,请务必提前研究字典攻击。

在实现它之后,我将进行测试以确保算法永远不会发生冲突。如果碰撞率很高,那么我会玩弄参数(使用的名词数量,使用的动词数量,随机数的长度,单词总数,各种大小写等)

回答

如果通过用户友好的方式,意思是用户可以输入答案,那么我想我们应该朝另一个方向看。我已经看到并完成了针对初始随机密码的实现,该初始密码将随机的单词和数字选择为更容易且不易出错的字符串。

如果我们正在寻找一种在URL字符串中编码随机代码的方法,这是我已经解决了一段时间的问题,那么我所要做的就是使用64位编码的GUID。

回答

我们可以使用唯一的顺序键将建议的单词列表加载到数据表或者xml文件中。获取随机单词时,请使用随机数生成器来确定要通过其关键字提取哪些单词。如果将其中的2个串联,除非目标不是"真正的随机性",否则我认为不需要在字符串中包括数字。