如何在c#中生成优惠券代码?

我需要生成优惠券代码[5到10位],仅供一次使用。 什么是生成和检查是否使用的最佳方法?

编辑:我更喜欢字母数字字符 – 亚马逊像礼品券代码必须是唯一的。

生成凭证代码时 – 您应该考虑是否具有可预测的序列实际上是您想要的。

例如,凭证代码:ABC101,ABC102,ABC103等是相当可预测的。 用户可以很容易地猜出凭证代码。

为了防止这种情况 – 你需要一些防止随机猜测工作的方法。

两种方法:

  • 在您的优惠券代码中嵌入校验和。

    信用卡上的最后一个数字是校验和(校验位) – 当您以某种方式将其他数字相加时,可以确保有人正确输入了数字。 请参阅: http : //www.beachnet.com/~hstiles/cardtype.html (谷歌的第一个链接),了解如何为信用卡完成此操作。

  • 有一个很大的密钥空间,只有人口稀少。

    例如,如果要生成1,000个凭证 – 那么1,000,000的密钥空间意味着您应该能够使用随机生成(使用重复和顺序检查)来确保难以猜测另一个凭证代码。

这是一个使用大键空间方法的示例应用程序:

static Random random = new Random(); static void Main(string[] args) { int vouchersToGenerate = 10; int lengthOfVoucher = 10; List generatedVouchers = new List(); char[] keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890".ToCharArray(); Console.WriteLine("Vouchers: "); while(generatedVouchers.Count < vouchersToGenerate) { var voucher = GenerateVoucher(keys, lengthOfVoucher); if (!generatedVouchers.Contains(voucher)) { generatedVouchers.Add(voucher); Console.WriteLine("\t[#{0}] {1}", generatedVouchers.Count, voucher); } } Console.WriteLine("done"); Console.ReadLine(); } private static string GenerateVoucher(char[] keys, int lengthOfVoucher) { return Enumerable .Range(1, lengthOfVoucher) // for(i.. ) .Select(k => keys[random.Next(0, keys.Length - 1)]) // generate a new random char .Aggregate("", (e, c) => e + c); // join into a string } 

基于Will Hughes和Shekhar_Pro的答案(仅仅因为我发现这个问题很有趣)这里是另一个实现,但我对你的凭证代码长度的要求有点自由。

使用base 32编码器我发现你可以使用Tick值来生成字母数字字符串。 将滴答计数编码为基数32会产生13个字符的字符串,可对其进行格式化以使其更具可读性。

  public void GenerateCodes() { Random random = new Random(); DateTime timeValue = DateTime.MinValue; // Create 10 codes just to see the random generation. for(int i=0; i<10; ++i) { int rand = random.Next(3600)+1; // add one to avoid 0 result. timeValue = timeValue.AddMinutes(rand); byte[] b = System.BitConverter.GetBytes(timeValue.Ticks); string voucherCode = Transcoder.Base32Encode(b); Console.WriteLine(string.Format("{0}-{1}-{2}", voucherCode.Substring(0,4), voucherCode.Substring(4,4), voucherCode.Substring(8,5))); } } 

这是输出

 AARI-3RCP-AAAAA ACOM-AAZF-AIAAA ABIH-LV7W-AIAAA ADPL-26FL-AMAAA ABBL-W6LV-AQAAA ADTP-HFIR-AYAAA ACDG-JH5K-A4AAA ADDE-GTST-BEAAA AAWL-3ZNN-BIAAA AAGK-4G3Y-BQAAA 

如果您为Random对象使用已知种子并记住您已经创建了多少代码,则可以继续生成代码; 例如,如果您需要更多代码并且想要确定您不会生成重复项。

这是一种方法:生成10000到9999999999之间的一堆唯一数字,将它放在数据库中。 每次向用户提供一个用户时,请将其标记为已使用(如果您尝试节省空间,则将其删除)。

编辑:在开头生成唯一的字母数字值。 您可能需要保留它们以进行validation(正如其他人指出的那样)。

如果您的应用程序仅限于使用数字数字,那么我认为Timestamps( DateTime.Now.Ticks )可以是每次获取唯一代码的好方法。 您可以使用随机数字,但这会产生检查已经发出的每个数字的开销。 如果你也可以使用字母表,那么肯定会使用GUID。

为了检查它是否已被使用,您需要维护一个数据库并查询它以检查其有效性。

如果您更喜欢字母数字,可以使用Guid.NewGuid()方法:

 Guid g = Guid.NewGuid(); Random rn = new Random(); string gs = g.ToString(); int randomInt = rn.Next(5,10+1); Console.WriteLine(gs.Substring(gs.Length - randomInt - 1, randomInt)); 

检查它是否未使用存储somwhere以前生成的代码并进行比较。

 private void AutoPurchaseVouNo1() { try { int Num = 0; con.Close(); con.Open(); string incre = "SELECT MAX(VoucherNoint+1) FROM tbl_PurchaseAllCompany"; SqlCommand command = new SqlCommand(incre, con); if (Convert.IsDBNull(command.ExecuteScalar())) { Num = 100; txtVoucherNoInt1.Text = Convert.ToString(Num); txtVoucherNo1.Text = Convert.ToString("ABC" + Num); } else { Num = (int)(command.ExecuteScalar()); txtVoucherNoInt1.Text = Convert.ToString(Num); txtVoucherNo1.Text = Convert.ToString("ABC" + Num); } con.Close(); } catch (Exception ex) { MessageBox.Show("Error: " + ex, "Error !!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } 

尝试使用此方法创建凭证编号,如ABC100,ABC101,ABC102等。

试试这个代码

  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var stringChars = new char[15]; for (int i = 0; i < stringChars.Length; i++) { stringChars[i] = chars[random.Next(chars.Length)]; }