SaidbakR
SaidbakR

Reputation: 13554

Reducing timestamp length in PHP using hash

I have coded my own implementation that generate 36 character's length identifier, you could say my own UUID, it should be something like the following:

  1. Current timestamp value padded with - till length 11
  2. Random 4 characters Upper case, lower case and digit characters followed by -
  3. Random 20 characters Upper case, lower case and digit characters

Also the database table's field that handles that ID, will be in bin collation to make its values case sensitive.

The result ID may be something like the following example:

1491681481-TI5b-7aCPMLK9a7MMLoSdhr5d

Here, the timestamp length is 10 and I want to decrease that length and replace the difference with -. I have tried to search for available hashing algorithms available in PHP:

foreach(hash_algos() as $alg){
        $h = hash($alg,1491681054);
        echo $alg."==>".$h."== Length ". strlen($h)."\n<br>";
    }

I found that there are some algorithms returns 8 characters length such as

  1. adler32
  2. crc32
  3. crc32b
  4. fnv132
  5. fnv1a32

Those hashing algorithms is fine for me. However, I'm afraid of collision.

I need to know the probability of collision for those algorithms where the source string is only a decimal number? In other words, does the input type or formating should reduce the collision probability for any one of those algorithms?

Upvotes: 0

Views: 722

Answers (1)

SaidbakR
SaidbakR

Reputation: 13554

According to maraca comment, I have made a simple implementation that convert the decimal value of the timestamp to number based on 62 i.e the sum of numbers, uppercase and lowercase of English alphabet as follows:

<?php

$stem = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

$old = 10; //original base -decimal-
$new = strlen($stem); //new base
$num = 1491681054; // decimal input
$out = '';
while($num > 0){
   $devide =  $num/$new ;    
   $result =  explode('.',$devide)[0]// could use floor();    
   $remind = $devide - $result;    
   $num = $result;
   $out = substr($stem,round($remind * $new),1).$out;
}

echo "<hr>";
echo $out;
// returns 1CWWnQ

By this way the the decimal number of length 10 is turned to a number of base 62 of length 6 characters only. Change to the alphabet characters order, may lead to change the output result, also we may able to increase the base by adding more symbols. (but be ware if the id will be used in a URL)

Reference

Upvotes: 1

Related Questions