Create short hash in PHP

10,131

Solution 1

If you want to be assured of never having a collision, your best bet is to maintain a database of valid hashes and compare against that database when generating new hashes.

If you think you will have a high volume, you may want to pre-generate the hashes so that you have a "haystack" of them ready to use. Some people do this with random numbers because hardware random number generators can only produce numbers at a certain rate.

Solution 2

The shortest useful hash algorithm would be md5. Md5 generates 16 bytes=128 bit hash. if you use base 64 encoding, that is, 6 useful bits per byte/char.

You should be able to reduce the md5 to 22 characters (leaving the trailing padding introduced by b64).

This has an added advantage of using the same for legal filenames. You 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 does not mess up the url with special characters.

Solution 3

You can use substr on a SHA1 or MD5. The chance of a collision with a substr'd hash is the same as a hash that's designed to be the shorter length.

Or if all you really want is to generate a unique key, you can do something like this:

define('KEY_CHARS', 'acefghjkpqrstwxyz23456789'); // characters which cannot be confused phonetically or by bad handwriting

function generateKey($len = 8) {
    $k = str_repeat('.', $len);
    while ($len--) {
        $k[$len] = substr(KEY_CHARS, mt_rand(0, strlen(KEY_CHARS) - 1), 1);
    }
    return $k;
}
Share:
10,131
PeeHaa
Author by

PeeHaa

So long SO main o/ and thanks for all the fish Check out my personal website or check out one of the open source projects I'm currently working on: Jeeves - A headless chatbot for the PHP room GitHub Minifine - JS and CSS minifier GitHub Requestable - online webservice for testing and debugging HTTP / REST requests GitHub OpCacheGUI - a nice webinterface for PHP's OpCache GitHub EmailTester - an online emailaddress validation regex tester GitHub Commentar - an open source PHP5.4+ commenting system GitHub HexDump - an online hex viewer GitHub RichUploader - a private filehoster GitHub PHP OAuth library GitHub Proposal for the new beginners tutorial on php.net GitHub I've created a close-voting Chrome plugin available at GitHub to help clean up Stack Overflow. If you would like to see what other projects I'm working on please visit my GitHub or drop me a line in the PHP chat.

Updated on July 02, 2022

Comments

  • PeeHaa
    PeeHaa about 2 years

    This has been asked numerous times here on SO. But I haven't found a solution for my problem.

    I want to create a short hash (let's say max 8 chars) for an invitation system. I cannot use base[X] encoding because that would be too easy to guess. I cannot just trim extra characters of e.g. an MD5 hash, because I think the problem of collisions will come up at some time then.

    Is there a solution for this?

  • Boann
    Boann over 12 years
    @OliCharlesworth: It's random? Gotta be better than the old md5(rand().uniqid().time()) code one sees thrown around.
  • Oliver Charlesworth
    Oliver Charlesworth over 12 years
    @Boann: If you want unique, the only way to achieve this is to store details about previously-generated IDs.
  • Boann
    Boann over 12 years
    @Juhana @OliCharlesworth: Hmmm, okay. OP could add an incrementing integer to it each time he generates an invitation. E.g., $invitationKey = generateKey() . '.' . (++$invitationNumber). Then it's both unguessable and unique.