【发布时间】:2011-01-06 10:00:21
【问题描述】:
I recently posted this question 关于用户可以在线兑换的类似礼品卡的优惠券的代码。我想在大键空间、低猜测性和人类可读性之间找到最佳折衷。现在我开始实施了,我意识到我遇到了另一个问题,更多的是算法挑战。
假设我采用某种代码格式 - 为简单起见,假设从 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,但它们神奇地使上述所有令人头疼的问题都消失了。不过,我觉得这个很有趣,也许你也是。我很想听听一些替代建议。你有什么?
谢谢!
【问题讨论】:
-
“随着系统积累更多数据,它会变慢。”嗯,有点。 log N 可能会减慢速度。如果是这样,当你有 1,000 张卡时需要 10 毫秒的检查,而当你有 十亿 卡时需要 30 毫秒 - 几乎不值得担心。请记住,每次使用礼品卡时,您都会遇到完全相同的查找,而您绝对无法避免这种情况。
-
GUID 绝对不会“神奇地”使碰撞成为不可能——它们足够长,以至于碰撞变得如此不可能,以至于几乎对所有目的都无关紧要——并且有不同类型的 GUID,其中一些这是完全可以预测的。
-
M. Borgwardt,我并不是说 GUID 实际上使用魔法来使碰撞变得不可能。每个人都知道他们使用精灵粉。
-
嗯,我该选择哪个答案,技术上最正确、最有创意的答案,还是我真正会使用的答案?无论如何,每个人都会获得支持!谢谢。
-
请注意,在您的乱序字母示例中,两个生成的代码只有 1 个字母不同,并且两个字母(“W”和“E”)在标准美式键盘上彼此相邻!我的意思是,您可能需要注意可能被单个字符错误输入的代码。也许确保生成的每个代码与其他代码至少有 2 个字符不同。这需要时间,但现在计算机速度非常快......