ruby-on-rails – 产生独特的,难以猜测的“优惠券”代码
我的Rails应用程序需要为用户生成电子优惠券.每个优惠券都应该有一个独特的优惠券代码,可以在我们的系统上兑换.
例如免费卷饼的优惠券.用户A收到免费卷饼的优惠券,然后用户B收到免费卷饼的优惠券. 2张优惠券应该有独特的优惠券代码. 生成不容易伪造的代码的最佳方式是什么?我不希望用户以随机数字输入成功率很高,并兑换其他人的优惠券. 我想这个想法就像一张背面有唯一号码的礼品卡是我正在寻找的. 解决方法
代码需要不可估量,因为在给予用户奖励之前您可以执行的唯一验证是检查他们输入的代码是否存在于“已发出”代码列表中.
>这意味着该格式的所有可能代码的数量远远大于要发行的代码数量.根据简单地尝试代码(考虑重复尝试的脚本)的简单性,那么您可能需要所有可能的代码超过已发布的代码的百万分之一或十亿以上.这听起来很高,但可能在相对较短的字符串. 这样一个安全代码的出发点是加密PRNG的输出. Ruby具有securerandom库,您可以使用它来获取如下原始代码: require 'securerandom' SecureRandom.hex # => "78c231af76a14ef9952406add6da5d42" 这段代码足够长,可以覆盖任何实际数量的凭证(每个人都有数百万个),没有任何有意义的重复机会或容易猜测.但是,从物理副本输入是有点尴尬. 一旦你知道如何产生一个随机的,几乎无法估量的代码,你的下一个问题就是理解用户体验,并决定你可以以可用性的名义实际地危害安全性.您需要牢记最终用户的价值,因此有可能尝试获取有效的代码.我不能为你答复,但可以提出一些关于可用性的一般观点: >避免模糊字符在打印中,有时难以看到1,I和l之间的区别.我们经常明白它应该是从上下文,但是一个随机的字符串没有这个上下文.通过测试0对O,5对S等,不得不尝试一些代码的差异,这将是一个糟糕的用户体验. 把这些都放在一起,这就是我可以生成一个可用的代码: # Random,unguessable number as a base20 string # .reverse ensures we don't use first character (which may not take all values) raw_string = SecureRandom.random_number( 2**80 ).to_s( 20 ).reverse # e.g. "3ecg4f2f3d2ei0236gi" # Convert Ruby base 20 to better characters for user experience long_code = raw_string.tr( '0123456789abcdefghij','234679QWERTYUPADFGHX' ) # e.g. "6AUF7D4D6P4AH246QFH" # Format the code for printing short_code = long_code[0..3] + '-' + long_code[4..7] + '-' + long_code[8..11] # e.g. "6AUF-7D4D-6P4A" 这种格式有20 ** 12个有效的代码,这意味着你可以发出十亿个你自己的代码,一个用户只需猜到一个正确的代码就有四分之一的机会.在密码学圈子中,这是非常糟糕的(这个代码对本地快速攻击是不安全的),但是对于注册用户提供免费卷饼的网络表单,以及在哪里你会注意到一个用脚本尝试四百万次的人,这是可以的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |