views:

1156

answers:

7

So I need to generate a code that can be tied to a specific user/prospect with a dollar amount built into it. It needs to be reversible so that client application can confirm the validity of the code and apply the discount a manager intends.

I'd like to make the code as short as possible but it needs to be well obfuscated so that the salesmen cannot start messing with it on their own.

I can come up with something myself bouncing numbers around, dividing by pi and converting to hex and whatnot but I'd be really interested in ideas or best practices from the community.

I'm doing this in C# but I expect that methods from any language can be translated.

edit: to clarify. I can't store this stuff ahead of time, the codes have to be built on the fly and carry all the information with them.

eg. Salesman 14 calls in about client 773 and wants to give them $500 off their order. 14, 773 and 500 must be in the coupon code and able to be extracted in the client app after the salesman keys in the code.

+1  A: 

I would use the customer code and the coupon expiration date. As for verification, you could just store valid coupons in your database and verify off that. You could scan the coupon table once a day to purge expired codes.

Bill the Lizard
There are countries (like Switzerland) where by law coupons never expire (even though they usually have an expiration date printed on the coupon). Replace the expiration date by issue date then.
Ralph Rickenbach
I like this answer because it offers a good alternative to all other answers that rely on cryptography. The only thing to note about this solution is that you can't verify coupon codes in offline mode.
Alexander
A slightly cleaner solution leading to shorter coupon codes, is to generate completely random short coupon IDs (e.g., 8 alphanumeric digits long), store them in the database together with all the relevant information about the coupon, such as customer ID, rep ID, coupon value, expiration...
Alexander
@Alexander, you're right, that would be shorter. With my proposed solution each coupon code would be unique, but that's not a stated goal of the problem.
Bill the Lizard
+2  A: 

How clever are your salesmen (or women)? Could you just base 64 encode the value?

Check here for how to base64 encode and decode:

http://arcanecode.wordpress.com/2007/03/21/encoding-strings-to-base64-in-c/

Other than that I would encrypt the value with a key known by you and the client application.

Arry
They're surprisingly clever at times. esp when their commission is riding on it.
Echostorm
Then encryption is the way to go, Treb's suggestion will work.
Arry
+5  A: 

Sounds like a case for asymetric encryption. You could give out the public key to everybody, thus providing them with the info for validating the coupon, but the ability to create a cupon would rest with the owner of the private key (= you).

I would create a coupon class that serialises to xml, and then encrypt the xml string. Validation would be to decrypt the string and see if it is valid xml (I recommend not to deserialise the object without checking this before).

Treb
+5  A: 

Generate a public/private key pair for signing. Digitally sign the combination of user ID and coupon value using the private key. Publish the coupon value + signature as the coupon code, encoded, for example, using letters and numbers. The client application would verify the code by recreating the combination of data that was originally signed (e.g., prepend the user ID to the coupon value) and then verifying the digital signature.

Alexander
Note: you will still have to have points of sale report what coupons have been used fairly frequently to minimize the risk of a coupon being used twice.
Neall
Sure, ensuring that a coupon code is only used once is left as an exercise to the reader. Also, the signed data needs to include more information, so that it's possible to issue several coupons for the same value and for the same customer + sales rep combination.
Alexander
For more information, http://en.wikipedia.org/wiki/Public-key_cryptography and a Google search are useful.
ICR
Include the salesrep or POS number to insure validity only on this POS or by this salesrep. Include a time code such that the coupon can only be entered within a certain timeframe.
Ralph Rickenbach
Works perfectly, but bear in mind that the codes will be rather long.
Nick Johnson
+2  A: 

I'm guessing from way you've phrased the question you don't want to store the codes in a database (if you did, you could simply verify each code against the database)

So, what you could do is take all the pertinent information about what is in the coupon, then hash it together with a secret salt to prevent tampering.

Thus, suppose you wanted a coupon for user 23 worth $200, you might build up a string like "23_200", and calculate an MD5 hash with a secret salt of "BillTheLizard" to get 2671519131e974ee6fc746151e98f4a8, thus the complete code you give the customer is 200_23_2671519131e974ee6fc746151e98f4a8

Now when you received the code, you break it apart, and check that md5("200_23"+secret) = 2671519131e974ee6fc746151e98f4a8 to verify the value

Edit: If an 32 character hash is too long, you could always truncate it, e.g. chopping it down to 8 chars would still give you 4294967296 different hash values.

Paul Dixon
In my experience, (sales)people will go into great lengths to tamper with such a system for personal profit. For example, they will hire someone to find out the secret salt from the client application. Asymmetric cryptography is slightly more reliable in this scenario.
Alexander
A: 

This is just to sum up the answers so far. There are two main distinct ways of generating such coupon codes:

  1. Centralized solution: the information about each coupon is stored in your database. The coupon code can then be randomly generated and short -- it's just a reference to a record in your database that contains all the necessary information, such as coupon value, customer ID, rep ID. Verifying such a code requires online access to your servers.

  2. Decentralized solution: the coupon is a standalone piece of information that can be verified in offline mode, without accessing any of your servers. As a result, the coupon code has to contain some (or even all) of the information. The most secure way is to use asymmetric cryptography so that nobody other than the holder of the private key (you) can generate coupons.

Alexander
+1  A: 

Steve Gibson talks about one time passwords on his website, but there's no reason why you couldn't use it to create one time coupon codes: http://grc.com/ppp

kpax