我正在设计一个网站进行实验,会有一个按钮,用户必须单击并按住一段时间,然后释放,然后客户端向服务器提交 AJAX 事件。
但是,为了防止自动点击机器人和快速垃圾邮件,我希望保持时间非常真实且不可跳过,例如进行一些计算。关键是浪费实际的 CPU 时间,这样你就不能简单地猜测 AJAX 回调值或调快系统时钟来绕过它。
有没有什么算法可以
- 在服务器上快速轻松地生成挑战
- 在客户端执行需要一些时间,没有欺骗或缩短时间。
- 轻松快速地验证服务器上的响应结果?
您正在寻找工作量证明系统。
最流行的算法似乎是Hashcash(也在Wikipedia上),它用于比特币等。基本思想是要求客户端程序找到具有一定数量前导零的哈希,这是他们必须用蛮力解决的问题。
基本上,它是这样工作的:客户端有某种令牌。对于电子邮件,这通常是收件人的电子邮件地址和今天的日期。所以它可能看起来像这样:
bob@example.com:04102011
客户端现在必须找到一个随机字符串放在前面:
asdlkfjasdlbob@example.com:04202011
这样它的散列就有一堆前导 0。(我的例子不起作用,因为我只是编了一个数字。)
然后,在您这边,您只需要获取这个随机输入并在其上运行一个哈希,以检查它是否以一堆 0 开头。这是一个非常快速的操作。
客户端必须花费大量 CPU 时间来找到正确的哈希的原因是这是一个蛮力问题。唯一知道要做的就是选择一个随机字符串,测试它,如果它不起作用,请选择另一个。
当然,由于您不发送电子邮件,因此您可能希望使用某种不同的令牌,而不是电子邮件地址和日期。但是,在您的情况下,这很容易:您可以在服务器端组成一个随机字符串并将其传递给客户端。
这种特定算法的一个优点是调整难度非常容易:只需更改您想要的前导零的数量即可。您需要的零越多,客户所需的时间就越长;但是,验证仍然需要相同的时间。