Write your own URL shortener

With Twitter and its 140 characters limit leading all the trends, URL shortening services are in extremely high demand. We have seen TinyURL in the past, now Bit.ly, Is.gd, Tr.im and dozens of others are joining the party to share the cake. Honestly saying, to me they’re all the same (except for ➡.ws for its cool name). With that being said however, it is interesting how they are doing it out there - what mechanism / algorithm / buzzword-here?

I curiously did some “research”es (well, another buzzword), and it seems in order to create the shorten URLs they are following the same steps:

  1. Insert the original (long) URL into the database
  2. Get the insert ID. If the URL already exists, take its row ID. Let’s say we got 123456.
  3. Convert the ID 123456 into something even shorter, let’s say “am4k”
  4. Make use of Apache’s mod_rewrite so that any request to http://host.com/am4k will reach http://host.com/redir_script.php?code=am4k instead.
  5. In redir_script.php the value “am4k” is converted back into base10′s 123456 and the corresponding URL is queried back from database
  6. If a URL is found, redirect the request to it.

It is simple enough… except for step 3 and 4. Which conversion is there, and how is the .htaccess written?

So I did some other buzzword-here, and it turned out base36 encoding is taking place. According to Wikipedia, “the choice of 36 is convenient in that the digits can be represented using the Arabic numerals 0-9 and the Latin letters A-Z”. There is a handy conversion table too:

Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Base 36 0 1 2 3 4 5 6 7 8 9 A B C D E F G H
Decimal 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
Base 36 I J K L M N O P Q R S T U V W X Y Z

Even better, PHP takes only one line of code to convert between decimal and base36, as shown on the same Wiki page:

$base_36 = "ZAQFG"; //Sample Base 36 Number
$decimal = "7654321"; //Sample Decimal Number
echo base_convert($base_36,36,10); //Outputs $base_36 converted to decimal
echo base_convert($decimal,10,36); //Outputs $decimal converted to base 36

In our example, 123456 will be converted into its tidy equivalent base36 2n9c (not am4k, my very bad).

As for the mod_rewrite thing, as I am not a .htaccess master, I copied this thing that has been working perfectly so far from CodeIgniter forum:

RewriteEngine On
RewriteBase /
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to redir.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ redir.php?code=$1 [L]

With this, all of the hardest parts are done, leave the remains being simple MySQL database, queries and HTML form handling. To save you from getting boring, I’ll omit it.

Instead, let’s see a demo hereThe source code of the demo are can be downloaded from the same server

  • Hi
    Thank you for this very useful post.  I have taken the code and created a URL shortener and I am very much a beginner (clueless) when it comes to php and mysql.
    I was wondering how to just show the short URL without all the text.  LIke this Long URL of 218 characters has now been shortened to this short URL of 15 characters.    I prefer just to show the shortened URL without the sentence.  Any idea how to do that?  When I remove things like %d or %s then the shortener no longer works.

  • Hi.
    If you keep the source untouched, take a look at index.php, line 25:

    $shorten_url = "{$config['host']}/$code";

    $shorten_url is the URL you want. Just echo() it.

  • The download ur is not working please upload again

  • Hello,

    Sorry for that. Reuploaded.

  • wow, nice script man! Simple and works.  I’m going to add some bit.ly functionality to it soon. rock on

  • Just what I was looking for! A URL shortner that actually works. Thanks!

You can follow any responses to this entry through the RSS 2.0 feed.

Trackbacks / Pingbacks