tags:

views:

167

answers:

5

A Ticket has a integer ID.

We decided users should not interact (see, enter as search parameter) the integer ID, because it is sequential, predictable.

So the users should work with a encrypted ID. It should have eight chars, between letters and numbers, avoiding those who look like (0, o, 1, l, 5, s, u, v), and not being sequential.

Which algorithm do you think is the best for generating this encrypted id, this two-way convertible string? (from id to encrypted, from encrypted to id)

thanks!

edit: hashed => encrypted

+4  A: 

A hash is by definition not convertible back to the original.

What you are looking for is encryption, if you want the both-way-conversion to be done programmatically.

Alternatively, you can use the database-based approach. You generate a hash (or even better a unique identifier) for an integer and store them both in a mapping table. Then you can easily find the original based on its hash (identifier).

Developer Art
Yeah, except you might as well generate a GUID if all you're doing is mapping.
Noldorin
Agree. Will be safer.
Developer Art
+1  A: 

One simplistic approach:

  • Declare a string containing all the characters you do want to use.
  • To take a hash, create a new instance of Random with the ticket ID as the seed
  • Take the first 8 random numbers from this Random instance, and use those numbers to index into the string to determine the 8 random characters.

However, this really will create a hash in that it may well not be unique (or reversible). Are you sure that's okay for your purposes?

Why not generate a random "visible ticket ID" when you create a new ticket, repeatedly generating random strings of 8 (or more?) characters until you avoid a collision - then store that visible ticket ID along with the ticket data (so you can search for it later, when the user presents it to you).

The larger your alphabet or the more characters you use, the smaller the chance is of a collision.

Note that one advantage of generating a random "visible ID" which isn't based on the sequential ticket ID is that you're not relying on security through obscurity... if you use something which predictably creates the same string from the same ID then if anyone works out that algorithm, you're effectively back to where you started (they can work out the "current" sequence number and generated the next visible ticket ID).

Jon Skeet
A: 

I think you dont want to hash the data, but to encode it. (Hashing is a ONE WAY algorithm)

To create an encoder/decoder you just do the following:

Encode - Create a set of valid symbols - take the ID, divide it by the number of symbols you have --> Remainder becomes the index in you symbols aray --> append this letter to the ones you already have. - take the floored result and start by step 2 until you have a result smaller then 1

Decode: Take 1st symbol, and get the index of it in your array. add it to the running total * elements in your symbol array take next symbol and continue at step 2

Heiko Hatzfeld
A: 

If all you are worried about is the predictability of the id in the URL, you could simply add another column to your user table that contains a hash of the row id. You wouldn't necessarily have to use a reversible algorithm and you could ensure the hash was unique by checking the other rows in the table.

You would probably want to add an index on this column if performance is an issue because you would be selecting on it frequently.

ctford
A: 

You could create an encrypted value for the user to see and work with and then decrypt it when working with it. I think a better solution would be to create a hashed ID value as part of the object as others have suggested, but if you wanted to go the encrypt/decrypt route the below is what we did for encrypting id's on the fly. You could encrypt the id to a string and show that string to the user, then decrypt the string when passed in from the user.

We implemented a wrapper around the 'DESCryptoServiceProvider' class so could encrypt a string and decrypt back to a string. We use this to encrpt ID's in query strings. We ToString() the ids to make them strings we can then encrypt. Our wrapper class Encrypt method returns a base64 encoded string. Our wrapper class takes care of converting string input into byte array, encrypting and returning encrypted byte array as base64 encoded string. The Decrypt method on our wrapper takes a string, the base64 encoded string, and decrypt it to a clear text string. You would then have to parse the clear text back into an int. One note if using in url is you have to UrlEncode the base64 encoded string before putting it in a url.

We make the keys configurable so can share keys across machines for web farming so ids encrypted on one web box can be decrypted on others.

Binz