Jam*_*Orr 20 algorithm collision
我最近发布了一个关于用户可以在线兑换的礼品卡式代码的代码.我想找到大键空间,低可猜测性和人类可读性之间的最佳权衡.现在,我正在实现,我意识到我完全有另一个问题,更多的是算法挑战.
让我们假设我采用了一些代码格式 - 简单来说从A到Z有10个字符,我开始生成代金券.这样做的正确算法是什么?!
我的第一种方法是将所有可能的代码编号从0到308,915,776,然后开始生成该范围内的随机数.这显然有一个很大的问题 - 我必须检查我的随机数与所有以前生成的凭证代码,如果它与现有的代码冲突,我将不得不丢弃代码并尝试另一个.随着系统累积更多数据,它将减慢速度.在极端情况下,只剩下一个代码,系统几乎不可能正确猜测它.
我可以预先生成所有代码并对其进行随机播放,然后按顺序使用它们.但这意味着我必须存储许多代码,实际上我的密钥空间比我描述的密钥空间大,所以我们讨论的是非常大量的数据.所以这也不太令人满意.
所以这让我顺序使用代码.我不想要可猜测的优惠券代码.购买凭证"AAAAAAAAAY"的用户如果输入"AAAAAAAAAZ",则不应该很有可能获得另一个有效代码.
我可以改变我的字母和我的位置,而不是
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'我用
'LYFZTGKBNDRAPWEOXQHVJSUMIC'
而不是位置
9 8 7 6 5 4 3 2 1 0这些职位是
1 8 0 7 5 4 3 9 2 6
使用这个逻辑,给出代码
LNWHDTECMA
下一个代码将是
LNEHDTECMA
这绝对不太可猜测.但是他们仍然只有一个角色相互关联,并且只给出其中两个优惠券你会知道哪个位置正在增加,并且你有90%的机会在24个猜测或更少的时间内获得下一个代码.
我的"逃生舱"就是抛弃所有这些并与GUID一起使用.他们拥有的字符比我希望用户输入的字符多,并且包含类似I/1和O/0的字符,但是他们神奇地让所有上述麻烦都消失了.不过,考虑到这一点我很开心,也许你也是.我很想听听其他一些建议.你有什么?
谢谢!
Mic*_*rdt 14
两个随机生成的代码冲突的可能性与用户猜测有效代码的可能性基本相同 - 并且您无法阻止用户猜测.所以你必须有一个比实际使用的代码数量大得多的密钥空间,随机冲突也是不太可能的(尽管,由于生日悖论,可能不太可能完全忽略它们,至少如果你想要你的代码合理地缩短),检查现有代码并在发生碰撞时重新生成是一种完全可行的策略.
Jas*_*n S 10
使用N位序列号R,结合级联对(R,S)的M位散列H,其中S是一些您不发布的秘密"salt"S .然后以您喜欢的任何可逆方式按字母顺序编码对(R,H).如果您喜欢MD5*或SHA等算法,但位数太高,那么只需采用标准哈希算法的M个最低有效位即可.
您可以轻松验证:解码字母数字编码,以便您可以看到R和H.然后计算H'=散列(R + S)并验证H = H'.
编辑: R可以是递增的序列号或随机或其他,只需确保您使用每个值不超过一次.
*在有人说"MD5坏了"之前,让我提醒你,MD5的已知弱点是碰撞攻击,而不是 前映像攻击.此外,通过使用未发布的秘密盐值,您拒绝攻击者测试您的安全机制的能力,除非他/她可以猜测盐值.如果你觉得偏执,选择两个盐值Sprefix和Ssuffix,并计算连接三元组的散列(Sprefix,R,Ssuffix).