开发者

how to generate a voucher code in c#?

I need to generate a voucher code[ 5 to 10 digit] for one time use only. what is the best way to generate and check if been used?

edited: I would prefer alpha-numeric characters - amazo开发者_开发技巧n like gift voucher codes that must be unique.


When generating voucher codes - you should consider whether having a sequence which is predictable is really what you want.

For example, Voucher Codes: ABC101, ABC102, ABC103 etc are fairly predictable. A user could quite easily guess voucher codes.

To protect against this - you need some way of preventing random guesses from working.

Two approaches:

  • Embed a checksum in your voucher codes.

    The last number on a credit card is a checksum (Check digit) - when you add up the other numbers in a certain way, lets you ensure someone has entered a number correctly. See: http://www.beachnet.com/~hstiles/cardtype.html (first link out of google) for how this is done for credit cards.

  • Have a large key-space, that is only sparsely populated.

    For example, if you want to generate 1,000 vouchers - then a key-space of 1,000,000 means you should be able to use random-generation (with duplicate and sequential checking) to ensure it's difficult to guess another voucher code.

Here's a sample app using the large key-space approach:

    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
    }


Building on the answers from Will Hughes & Shekhar_Pro (and just because I found this question interesting) here's another implementation but I've been a bit liberal with your requirement for the length of the voucher code.

Using a base 32 encoder I found you can use the Tick value to generate alpha-numeric strings. The encoding of a tick count to base 32 produces a 13 character string which can be formatted to make it more readable.

    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)));
        }
    }

Here's the output

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

If you use a known seed for the Random object and remember how many codes you have already created you can continue to generate codes; e.g. if you need more codes and want to be certain you won't generate duplicates.


Here's one way: Generate a bunch of unique numbers between 10000 and 9999999999 put it in a database. Every time you give one to a user, mark it as used (or delete it if you're trying to save space).

EDIT: Generate the unique alpha-numeric values in the beginning. You'll probably have to keep them around for validation (as others have pointed out).


If your app is limited to using only Numerical digits then i think Timestamps (DateTime.Now.Ticks) can be a good way to get unique code every time. You can use random nums but that will have overhead of checking every number that its been issued already or not. If you can use alphabets also then surely go with GUID.

For checking if its been used or not you need to maintain a database and query it to check for validity.


If you prefer alphanumerical, you could use Guid.NewGuid() method:

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));

To check if it was not used store somwhere previously generated codes and compare.


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);
        }
    }

Try this method for creating Voucher Number like ABC100, ABC101, ABC102, etc.


Try this code

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜