MD5 is not encryption, it is a hashing algorithm. There is a big difference between the two; most importantly, hashing cannot be reversed, unlike encryption, because multiple inputs will give the same output.
–
Michael MadsenAug 9 '09 at 14:25

Hi, Prashant. I see your new comment about using the string in a URL. I can think of a few approaches to make this work again, but maybe we'd be able to give an answer that fits your problem if you expanded on what kinds of inputs you expect to have, exactly why you're making an MD5 hash, and what you want to accomplish with the URL in the end. That way we can short-circuit any objections you may have with new solutions, or maybe even just suggest another approach, like @tvanfosson's Perfect Hash Function idea.
–
Blair ConradAug 15 '09 at 11:50

Hi @Blair: Actually there is nothing special in making URL's like this, I am just inspired by GMAIL message URL's they are making them like: http://mail.google.com/mail/?shva=1#inbox/14461a1185905642 and this is good because on logged in user can view there messages, in the same way in my app also only logged in users are allowed to perform any activity. So instead of giving URL like: http://examle.com/mail/18/ I wantto make them like http://examle.com/mail/14461a1185905642/.
–
PrashantOct 21 '09 at 4:10

... That's why I require some good of encryption function or technique which will not fail in any way and will produce output like google doing, no special chars only numbers and letters.
–
PrashantOct 21 '09 at 4:11

7 Answers
7

I like @RichieHindle's answer. However, if you're interested in losing fewer bits of fidelity (and thereby decreasing the risk of collisions), you could take the 128 bit value returned by the MD5 Hash, and encode it using ASCII85 (also known as Base85 encoding), instead of a hexadecimal-based encoding. This will give you the whole hash in 20 bytes (which is more than you wanted, but you could chop 2 bytes off, resulting in much less loss than removing 14 of the 32 bytes you'd get using hex encoding).

Edit: Prashant says 20 characters is close enough, and asked for sample code:

20 character are fine for me, how to apply your method in in C#? Can you please tell me, or should I ask another separate question for this??
–
PrashantAug 11 '09 at 6:35

4

Ok, this is fine, but the output contains special chars (? , & etc) but I want to pass this has string in URL as parameter so that on the next page I can decrypt it and show the output to the user, something like gmail is doing mail.google.com/mail/?zx=1xjighs8u7ewc&shva=1#inbox/1230e772c539f5e3 . If I'll pass ? or & in url then that will create problem. Can't we remove the special chars from final output to generate output something like "1230f774c459b5f3" (without special characters ??
–
PrashantAug 13 '09 at 4:05

You can just take as much of the MD5 hash as you need, and throw the rest away. All the bits have equal value, so there's no difference between doing that and using some hashing algorithm that natively produces fewer bits.

(If you're doing this for security reasons, remember that fewer bits makes hashes easier to crack, regardless of the algorithm. Even outside of security applications, fewer bits increase the risk of collisions. Also bear in mind that MD5 is relative insecure these days - SHA-1 or SHA-2 are considered more secure.)

Wouldn't this increase the chances of collision, though? I'm not expert in cryptography, but it just seems like a bad idea to be throwing away portions of a hash and still expect it to maintain its properties.
–
Thomas OwensAug 9 '09 at 14:18

Thomas: Well, it will happen in any case. A shorter hash inherently has a higher chance for collisions.
–
Mehrdad AfshariAug 9 '09 at 14:19

4

If the values are always smaller than the hash size, you can easily create a hash that won't have collisions. Collisions are only inherent when the size of the data is larger than the size of the hash because then every possible input cannot map one-to-one onto a different hash value.
–
tvanfossonAug 9 '09 at 14:25

3

You can't make it always unique - it's a hash, by definition it has collisions. The shorter you make it, the more likely a collision is.
–
Nick JohnsonAug 10 '09 at 16:08

u should be able to reduce the md5 to 22 characters (ascii). what you have is hex version where 2 bytes represent one actual byte

(leaving the trailing padding introduced by b64)

with an added advantage of using the same for legal filenames. (ofcourse u will have to substitute the default / and + characters with any other symbol which does not clash with file naming convention of your os.

base64 (by replacing / and +) ensures your hash doesnot mess up the url with special characters which may mean something else to your webserver

ASCII85 adds characters which are difficult to deal with when using as filenames and in urls