tags:

views:

160

answers:

6

I need a technique (an a pointer to sample code if you have) for generating conformation numbers for web payment. I don't want the customer to write down a long sequence like a GUID but I don't want it easily predictable as well.

Using C#

Thanks for all the tips. I decided on a format like this:

TdddRROOO

T = 2009 (next year will be U = 2010) ddd = days this year RR = two random numbers 000 = order number (I'll offset this so folks can't know the order number that day)

So the confirmation number will be something like P23477098

+1  A: 

You could do something with a mixture. Generate the first half of the key as a known, predictable value (e.g. 00001, 00002, 00003, etc.) and then generate the second half as a randomly generated value so it won't be predictable. Then, increment the "known, predictable" value so that you will never get a match.

Your unique code would then become: 00001-53481, 00002-43853, 00003-54511, etc.

Of course, I am sure there are libraries out there that probably do this already. (It might help if you specify what language you are using.)

JasCav
A: 

Just generate a random number between 100000 and 999999, for example. Also a good idea is to put some letters in front that identify that it is a confirmation number, such as CONF-843682 so that people will recognize it more easily when you ask for it.

Store the number in the database, together with an ID for the order and an expiry date (say 1 year).

Mark Byers
The number needs to be unique, so it would be necessary with this approach to check if the number exists then regenerate again until you get a free number.
Eric J.
This won't work because it is possible for the same random number to be generated more than once which would violate his "unique ID" requirement. (Hence, why I said my solution.)
JasCav
+1  A: 

Decide on the characters (char[] chars) that you want in your confirmation code, decide on the length of confirmation code (n), generate n random numbers (i_1, i_2, ... i_n) in the range [0..chars.Length) and return the string chars[i_1]chars[i_2]...chars[i_n].

In C#:

public string ConfirmationCode(char[] chars, int length, Random rg) {
    StringBuilder codeBuilder = new StringBuilder();
    for(int i = 0; i < length; i++) {
        int index = rg.Next(chars.Length);
        codeBuilder.Append(chars[index]);
    }
return codeBuilder.ToString();

For uniqueness, prepend the current time in yyyyMMddhhmmss format.

Jason
Thanks. I will shorten yyyyMMdd to T[n]T = 2009, n = days this year
ritu
A: 

You could do something like get a random number of a specified length, convert to base64 and add a checksum character.

rsp
A: 

How about something like Amazon's PayPhrase? Use a library like Faker (Ruby) or Data::Faker (Perl) to generate random phrases, or write your own utility. Then just use a simple hash function to convert the "confirmation phrase" into a number you can index.

As for C# there exists a port Ruby's Faker gem at http://github.com/slashdotdash/faker-cs

andykram
Never heard of this before but it looks good. I will give it a try.
ritu
Amazon PayPhrase is for checkout, not confirmation numbers
0A0D
PayPhrase is for checkout with regard to Amazon, but there's no reason you couldn't apply the same concept to confirmation numbers/phrases. In effect the phrase becomes a password that accesses the requisite information.
andykram
+1  A: 

I recent did same thing in PHP. We use random function in this class,

https://gallery.svn.sourceforge.net/svnroot/gallery/trunk/eval/gx/kohana/kohana/helpers/text.php

We use random('distinct', 8) to generate confirmation number. It generates strings like this,

4CFY24HJ
JH5AYL7J
2TVWTMJ5

As you can see, it has no confusing numbers/letters like (1/l, 0/O etc) so it makes it much clearer when customers have to read the numbers over the phone.

ZZ Coder
"no confusing numbers/letters" - This is awesome, never thought of this before.
ritu
Are you checking to see if the pre-generated confirmation # is already in the database?
0A0D
No need. Confirmation number is not a transaction ID. It doesn't have to be unique. It just needs to be hard to guess. If you also use it to identify the transaction, you need an unique index and then you just need to regenerate when you get duplicate key error.
ZZ Coder