生成独特的,难以猜测"优惠券" codeS [英] Generating unique, hard-to-guess "coupon" codes

查看:154
本文介绍了生成独特的,难以猜测"优惠券" codeS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Rails应用程序需要生成电子优惠券的用户。给每张优惠券应该有一个唯一的券code,可以在我们的系统被赎回。

My Rails app needs to generate electronic coupons for users. Each coupon given should have a unique coupon code that can be redeemed on our system.

例如一个免费的卷饼优惠券。 用户A 收到的优惠券免费的卷饼,然后用户B 收到的优惠券免费的卷饼。 2.券应该有独特的券codeS。

For example a coupon for a free burrito. User A receives a coupon for a free burrito and then User B receives a coupon for a free burrito. The 2 coupons should have unique coupon codes.

什么是生成一个code这样是不容易伪造的最佳方法是什么?我不希望用户能够输入随机数和兑换其他民族券的成功率很高。

What is the best way to generate a code like this that is not easily forged? I don't want users to have a high success rate of typing in random numbers and redeeming other peoples coupons.

我猜想它像一个礼品卡背面有一个唯一的号码是我所期待的。

I guess thinking about it like a gift card with a unique number on the back is what I am looking for.

推荐答案

在code必须是不可猜测的,因为只有验证就可以给他们的报酬是检查是否code用户之前执行他们进入存在于你的名单颁发的codeS。

The code needs to be unguessable, because the only verification you can perform before giving the user their reward is to check whether the code they entered exists in your list of "issued" codes.

  • 这意味着所有可能的codeS的该格式的数比codeS要发出的数目大得多,。这取决于它是多么容易简单地尝试codeS(觉得剧本反复尝试的),那么你可能需要的所有可能的codeS由一百万因子或十亿以上,多于发出codeS 。这听起来很高,但有可能在相对较短的字符串。

  • That means the number of all possible codes in that format is much larger than the number of codes you want to issue,. Depending on how easy it is to simply try codes (think of a script trying repeatedly), then you might need all possible codes to outnumber issued codes by a factor of a million or a billion or more. This sounds high, but is possible in relatively short strings.

这也意味着,codeS,你使用时必须作为随机地选择所有可能的codeS之内。这是必要的,以避免用户搞清楚,大多数有效的codeS开始以AAA为例。更复杂的用户可能会发现,你的随机codeS使用破解的随机数发生器(Ruby的默认兰特()快速,随机的数据统计好,但容易被破解这种方式,所以不要使用它)。

It also means that the codes that you use must be chosen as randomly as possible within all possible codes. This is necessary to avoid users figuring out that most valid codes start with "AAA" for example. More sophisticated users might spot that your "random" codes use a hackable random number generator (Ruby's default rand() is fast and statistically good for random data, but is hackable in this way, so don't use it).

的起点这样一个安全code将是从一个加密PRNG的输出。红宝石具有的SecureRandom 库,你可以用它来获得原始code是这样的:

The starting point for such a secure code would be the output from a cryptographic PRNG. Ruby has the securerandom library, which you can use to get a raw code like this:

require 'securerandom'
SecureRandom.hex
# => "78c231af76a14ef9952406add6da5d42"

这code是足够长支付凭证的任何实际数量(每百万每个人在这个星球上),没有重复或易于猜测的任何有意义的机会。然而,这是一个有点尴尬,从一个物理副本类型。

This code is long enough to cover any realistic number of vouchers (millions each for everyone on the planet), without any meaningful chance of repetition or being easy to guess. However, it is a bit awkward to type from a physical copy.

一旦你知道如何生成一个随机的,几乎不可猜测code,你的下一个问题是理解用户体验,并决定多少你可以实事求是地危及安全的可用性的名称。你需要牢记的价值给最终用户,因此如何努力,有人可能试图得到一个有效的code。我不能回答这个问题你,但可以做一些基本点约可用性:

Once you know how to generate a random, practically unguessable code, your next problem is understanding user experience and deciding how much you can realistically compromise security in the name of usability. You need to bear in mind the value to the end user, and therefore how hard someone might try to get a valid code. I cannot answer that for you, but can make some general points about usability:

  • 避免含糊不清的人物。在打印方面,它有时是很难看到的 1 的区别我为例。我们经常会明白它应该是从上下文,但字符的随机字符串没有这样的背景下。这将是一个不好的用户体验必须通过测试,以尝试的code一些变化 0 VS 0 5 VS 取值等等。

  • Avoid ambiguous characters. In print, it is sometimes difficult to see the difference between 1, I and l for example. We often understand what it is supposed to be from context, but a randomised string of characters does not have this context. It would be a bad user experience to have to try several variations of a code by testing 0 vs O, 5 vs S etc.

使用任何小写或大写字母开头,但不能同时使用。区分大小写将不被理解或之后的用户有些%年龄。

Use either lower case or upper case letters but not both. Case sensitivity will not be understood or followed by some %age of your users.

匹配codeS的时候接受变化。允许空格和破折号。或许甚至可以让 0 0 意味着同样的事情。这最好通过所以它是在正确的情况下,处理输入文字进行,带状隔板字符等

Accept variations when matching codes. Allow spaces and dashes. Perhaps even allow 0 and O to mean the same thing. This is best done by processing the input text so it is in the right case, strip separator characters etc.

在打印,分开code成几个小部分,它会更容易为用户查找字符串在自己的位置,并在一次键入几个字符。

In print, separate the code into a few small parts, it will be easier for the user to find their place in the string and type a few characters at once.

不要让code太长。我建议12个字符,在3组4。

Don't make the code too long. I would suggest 12 characters, in 3 groups of 4.

下面是一个有趣的 - 你可能要扫描的code可能的粗话,或避免将生成它们的字符。如果你的code仅包含字符 K U F C ,那么就不会有得罪用户的机会很高。这通常不是一个问题,因为用户不会看到大多数计算机安全codeS,但这些的人会在打印!

Here's an interesting one - you may want to scan the code for possible rude words, or avoid the characters that would generate them. If your code contained only the characters K, U, F, C, then there would be a high chance of offending a user. This isn't usually a concern because users do not see most computer secure codes, but these ones will be in print!

把所有在一起,这是我怎么可能会生成一个可用的code:

Putting that all together, this is how I might generate a usable code:

# 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 有效codeS这种格式,这意味着你可以发出一个十亿自己的$ C $的CS,并且将有之一,400万的机会,用户仅仅是猜测正确的。在密码界这将是非常糟糕(这code是不安全的反对快速的本地攻击),但对于一个Web表单提供免费的煎饼注册用户,并在那里你会发现一个人试图400万倍与脚本,它是确定。

There are 20**12 valid codes in this format, which means you can issue a billion of your own codes, and there would be one in four million chance of a user simply guessing a correct one. In cryptography circles that would be very bad (this code is insecure against a fast local attack), but for a web form offering free burritos to registered users, and where you would notice a someone trying four million times with a script, it is ok.

这篇关于生成独特的,难以猜测"优惠券" codeS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆