1

I am setting up a voucher code system for a checkout written in C# and I want to be able to distribute unique vouchers that do the same thing, sort of like a product key.

Is there any way of generating unique (fairly short and preferably alpha-numeric) strings that will "hash" in some way to give the same result?

In other words, can I start with a defined voucher code and get multiple results for a reverse hash?

I'm sorry if I'm not explaining this very well - I can give more information if needed.

EDIT: I know that I could use a look-up table with pre-defined codes, but I was wondering if there is a way to auto-generate these codes to allow the system to scale easily.

2
  • which programming language? Have you got something like a user id or a e-mail of the person who will get the voucher code? Commented Nov 12, 2012 at 11:56
  • The code checking will be in C#, but I can use any method to generate the codes (they will be printed). The codes will be physically printed and handed out so there is no way of tying them to a particular person. Commented Nov 12, 2012 at 11:58

3 Answers 3

4

Here's a thought...

Start w/ some secret password: "100:mypass:yourpass"

then md5 that: you'll get

md5("10:mypass:yourpass")=f6ff5421b31e609c7dcd19c4a462caa0

'key 1'=>  left 16 chars of md5 = 'f6ff5421b31e60'

  run the right 16 chars of the md5 it into another md5:

md5('7dcd19c4a462caa0') = 582fbfb7a035d08094cdef57d88f720e

'key 2' => '582fbfb7a035d080'

[repeat again here, and again... and again, ]

...

Not sure on the 'distribution' point on this, e.g. if it will be running on a POS type gift card or voucher card system or what, but if you notice I put 3 components into the 'password', this value could contain the total legitimate keys (split on ":", resulting in a break on 100 valid keys ), a system (distributor) password, and a local system password that would be required to 'verify' or 'match' on a 'good' key. You could just do a quick scan to see if the key exists or not and write an invalidation routine locally. I know, my math genius friends would probably say there's a better, more secure and effective way but hey... this is what you asked for right? I'm a simple man and like simple things... but you could make it more complicated by allowing for ranges too... e.g. pass=> "100:1000:pass1:pass2" that way you could test the 100->1000th md5's partial keys... Cheers!!

Sign up to request clarification or add additional context in comments.

1 Comment

This would appear to be a great solution so I am accepting it. However, what I used in the end was a known string concatenated with a random string and a checksum calculated from the two.
1

What you are looking for is called Perfect hash function.

Here you can find an article about how to efficiently generate perfect hash for large key sets.

And here you can find a c# minimum perfect hash function generator.

2 Comments

Actually, from your links it looks like I want the opposite. I'm looking for a way of guaranteeing collisions for multiple keys. Also, the full list of keys is not necessarily known before the hash is.
The last link is broken.
0

you could use a hash generated via the current date/time

<!-- language: c# -->
byte[] ByteArray = Encoding.UTF8.GetBytes(System.DateTime.Now.ToString());
MD5 md5 = MD5.Create();
byte[] ByteResult = md5.ComputeHash(ByteArray);
StringBuilder result = new StringBuilder(ByteResult.Length * 2);
for (int i = 0; i < ByteResult.Length; i++)
    result.Append(ByteResult[i].ToString("X2"));
Console.WriteLine(result.ToString());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.