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

时间:2011-01-17 13:19:59

标签: c#

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

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

7 个答案:

答案 0 :(得分:16)

生成优惠券代码时 - 您应该考虑是否具有可预测的序列才是您想要的。

例如,凭证代码: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<string> generatedVouchers = new List<string>();
        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
    }

答案 1 :(得分:7)

以Will Hughes&amp;的答案为基础Shekhar_Pro(只是因为我发现这个问题很有意思)这是另一个实现,但我对你的代码长度要求有点自由。

使用base 32 encoder我发现您可以使用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对象使用已知种子并记住已创建的代码数量,则可以继续生成代码;例如如果您需要更多代码并且想要确定您不会生成重复项。

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

如果您更喜欢字母数字,可以使用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));

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

答案 5 :(得分:0)

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等。

答案 6 :(得分:0)

试试此代码

  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
                        var stringChars = new char[15];

                        for (int i = 0; i < stringChars.Length; i++)
                        {
                            stringChars[i] = chars[random.Next(chars.Length)];
                        }