0

I want to enable "Save" feature in my web app. I will send data to a PHP post receiver, and save the data in a MySQL row, so normally I can load it with its id like this:

site.com/content/123

But I want (just for the fancy looks) to use a "hash" (not sure if it's the right term) for this, like :

site.com/content/A2w7SqZ

just like jsFiddle does. How can I convert the id (integer) to a hash?

Example : http://jsfiddle.net/sfu24/

The only way I can think of is MD5. But it generates a very long string. I think 6 characters are more than enough.

So how can I make a hash system like jsfiddle?

Thanks for any help !

P.S. I'm sure this question has been asked million times. But I couldn't find it. If you know an already-existing answer, please post the link and I will delete the question.

jeff
  • 13,055
  • 29
  • 78
  • 136
  • you can build your own hash system. Loop through letters and numbers and append them randomly – Royal Bg Feb 15 '14 at 18:46
  • But I have only an integer as the seed. Now I found a method [here](http://stackoverflow.com/questions/2520794/php-generate-an-8-character-hash-from-an-integer) It proposes to take a substring of the MD5 hash. Will it work? Is it not dangerous? (Danger of conflict) ? – jeff Feb 15 '14 at 18:49
  • first of all what do you want to do? fancy looks or md5? md5 will not generate fancy strings like in your example. if you want to generate random chars, there is tons of functions here and there. choose one of them, generate random chars, save it with related id to database, read if you need and redirect to related id... – optional Feb 15 '14 at 18:53
  • @optional no, I want random chars (alphanumerics, upper & lowercase), they don't have to make sense. Let me change my example :) – jeff Feb 15 '14 at 18:54
  • @CengizFrostclaw do they have to be reversable? I mean do you want "12345" everytime to asnwers to "g4L3w9", or if you hash the string "12345" 5 times you will recieve 5 different hashes? – Royal Bg Feb 15 '14 at 18:56
  • @RoyalBg yes of course, I will load the content depending on the hash. But, I can save the hash into the database, so the "reversion" is not necessarily algorithmic. It may just be a lookup. I just need them to be unique. – jeff Feb 15 '14 at 18:58
  • @CengizFrostclaw I added a function which used one of my project.... read below – optional Feb 15 '14 at 18:59

3 Answers3

2

to generate random chars

function generate_random($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for($i = 0; $i < $length; $i ++) {
        $randomString .= $characters [rand ( 0, strlen ( $characters ) - 1 )];
    }
    return $randomString;
}
optional
  • 92
  • 6
  • Thanks, but this has a possibility of generating two equal strings. Small possibility, but it exists. – jeff Feb 15 '14 at 18:59
  • @CengizFrostclaw then your custom function can loopup in the DB and if the string is found - run again? – Royal Bg Feb 15 '14 at 19:02
  • @CengizFrostclaw this function generates random string which contains chars in $characters variable. $length is length of generated string.... for example generate_random(8); will generate you something like this: De1aSf3h – optional Feb 15 '14 at 19:03
  • Ok, Royal Bg is right. I was just looking for a single-shot way. But, even MD5 hash this danger, right? – jeff Feb 15 '14 at 19:06
  • MD5 has this danger more. Because "12345" will result in one and the same hash everytime. – Royal Bg Feb 15 '14 at 19:08
  • @CengizFrostclaw yes Royal Bg is right ... you must check the database if the generated code is unique. you can not find any function which generate unique string without checking database. or you may ad an sql query to this function for checking if it unique.. – optional Feb 15 '14 at 19:09
  • @RoyalBg my purpose is exactly that. Same content should not be saved twice. And I think I'm going to use this method because my webhost does not support hashids.. – jeff Feb 20 '14 at 20:53
1

Take a look as base_convert()

or the hashids

which will help you generate short hashes from numbers (like YouTube and Bitly).

MrSimpleMind
  • 7,890
  • 3
  • 40
  • 45
  • Thanks! I will try hashids now. – jeff Feb 15 '14 at 18:55
  • 1
    Wow, hashids is perfect for my example, because the data I want to save is actually an array of numbers. So your answer definitely saved my day ! Thanks :) – jeff Feb 15 '14 at 19:07
  • I was actually looking at this (url shortener techniques) some months ago too, I found a good algorithm site then which I try to find again but still no success. I will send the url here as soon as I find it. Happy that hashids helped you with your problem. :) – MrSimpleMind Feb 15 '14 at 19:10
  • It will, but there is a small problem. How do I convert the string "1,2,42,55" to the input of encrypt() ? I can explode them, but then what ? – jeff Feb 15 '14 at 19:11
1
function generateHash($int) {
    $rand_letters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $newstr = '';
    for ($i = 0; $i < strlen($int); $i++) {
        $newstr .= $rand_letters[rand(0, strlen($rand_letters)-1)];
    }
    return $newstr;
}

function myHash($int) {
    $newstr = generateHash($int);
    $result = $db->query("SELECT COUNT(*) FROM hashes WHERE hash = '$newstr';");
    if ($result->num_rows > 0) {
        myHash($int);
    }
    return $newstr;
}

echo myHash(973451);

You generate string on the base of the length of your passed integer. That's what generateHash() does. And myHash() uses this string, if it's already present, runs itself again, until generate not-present string, so returns it.

The hashes are random, so they are not straight reversable (they still can be), but "12345" will not result in one and the same string everytime.

Royal Bg
  • 6,988
  • 1
  • 18
  • 24