Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to generate codes for a URL shortening service in PHP?

Tags:

algorithm

php

I have to use this way to generate codes for a URL shortening service

  $code = substr(md5(uniqid(rand(), 1)), 3, 5);

but this is always generate a fixed length code (5 in this case) .

what if there is a large number of URLs in the database that can't stand the five symbols here ?

sorry for the bad English.

like image 770
Waseem Avatar asked Feb 28 '23 13:02

Waseem


1 Answers

You're going to have to store the URL so simply have a table:

  • URL: id, url

where id is an auto-increment sequence and the url column is indexed. This way each URL is unique. The simplest method is to simply use the ID but you can get shorter than that.

My suggestion would be to convert the ID to and from a base 62 (10 digits, 26 uppercase letters, 26 lowercase letters = 62) or possibly 64 (add _ and -).

By this I mean 1234 is really:

1 x 103 + 2 x 102 + 3 x 101 + 4 x 100

and there's a fairly simple algorithm for turning a number from and to it's base 10 form. So a base 62 "number" is:

1234 (base 10) = 19 x 621 + 56 x 620 = Jq

if my maths is right.

The following functions should do what you need.

$digits = range(0, 9) + range('A', 'Z') + range('a', 'z')

function from10($base10) {
  global $digits;
  $ret = '';
  $nd = count($digits);
  $n = $nd;
  while ($base10 > 0) {
    $r = $base10 % $n;
    $ret .= $digits[$r];
    $n = (int)($base10 / $n);
    $n *= $nd;
  }
  return $ret;
}

function to10($baseN) {
  global $digits;
  $nd = count($digits);
  $ret = 0;
  $n = $nd;
  for ($i=0; $i<strlen($baseN); $i++) {
    $ret += $n * $baseN[$i];
    $n *= $nd;
  }
  return $ret;
}

from10() converts 1234 to "qJ" (hopefully) and to10() converts "qJ" to 1234, unless my maths is off.

The digits are actually stored in reverse order (the equivalent of "one hundred and twenty three" being written out as "321") because that's easier to deal with and there is no need for the digits to be in any particular order.

like image 132
cletus Avatar answered Mar 22 '23 22:03

cletus