Search code examples
phphashipip-address

PHP Generate an unique hash from an IPADDRESS


I have a board and i want to disable registrations instead i want the users to be able to post freely with an unique ID based on their IPAddress

for example:

if "Joe" IP is 200.100.15.117, "Joe" nickname will become the hash function of 200.100.15.117

if "Joe" IP changes he will get another ID, that doesn't matter, i only want one unique ID per IPAddress

There are also two important things :

  • unique ID must be 8 characters long
  • hash should be secure, i don't want hackers be abble to crack my users IPaddresses

I thought in using an MD5 function and then trim it to 8 chars, but how unique is that ? is there a better way ?


Solution

  • EDIT According to OP comment on this answer.

    Code below uses BC Math library to translate a MD5 hash into a Base-90 string. This converts a 32 char string into a 20 char one. This is far from desired 8 chars but it is the minimum string length using ASCII range (it is possible to increase the base to Base-94 by using chars ' " \ [space] but this does not affect to the string length and instead may cause problems while handling data).

    $ip      = '200.100.15.117';
    $hash    = md5($ip);
    $chars16 = array(
        '0' => 0,  '1' => 1,  '2' => 2,  '3' => 3, '4' => 4,  '5' => 5,
        '6' => 6,  '7' => 7,  '8' => 8,  '9' => 9, 'a' => 10, 'b' => 11,
        'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15
    );
    $base10 = '0';
    for ($i = strlen($hash) - 1; $i > 0; $i--) {
        $base10 = bcadd($base10, bcmul($chars16[$hash[$i]], bcpow(16, $i)));
    }
    $chars   = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,;.:-_+*?!$%&@#~^=/<>[](){}`';
    $base    = (string)strlen($chars);
    $baseX   = '';
    while (bccomp($base10, $base) === 1 || bccomp($base10, $base) === 0) {
        $baseX  = substr($chars, bcmod($base10, $base), 1) . $baseX;
        $base10 = preg_replace('/\.\d*$/', '', bcdiv($base10, $base));
    }
    $baseX = substr($chars, $base10, 1) . $baseX;
    echo $baseX; // Shows: 1BS[JdZf/7J$J{ud&r5i