Metodos y Algoritmo para crear una URL corta (shorturl)

Intro

Hoy quería investigar sobre cómo crear un sistema de URL cortas; lo primero que hay que decir, es que hay cientos de servicios que te generan este tipo de URL, pero siempre es con el dominio de la herramienta, cosa que no es muy recomendable.

De las librerías(resumidas más abajo) que he podido analizar; todas guardan en una base de datos la URL y un identificador que será el que se envía como parámetro. Dentro de estas librerías, se puede separar en tres grupo por la forma de generar ese identificador:

  1. Las que crean un indice numérico incremental y lo utilizan como identificador.
  2. Las que crear un indice numérico incremental y luego encriptan este número y usan como identificador
  3. Las que ecriptan de algún modo la URL de destino y utilizan (el resultado de la encriptación) como identificador.

YourURL

Esta librería ha sido la primera en descartar; porque creo que usa la API de su web para realizar la tarea acortar la URL. Cabe destacar que es una aplicación bastante completa porque tiene una sección para ver el trafico que han tenido las URL generadas.

web: http://yourls.org

Rick URL Shortening Service

Esta librería (en .NET) es del primer grupo; que más o menos nos da una idea de como se monta el sistema.

El principal fallo que le veo; es que se pasa como identificador el ID (numérico) como parámetro y no queda demasiado estético.

En el siguiente screencast (del autor de esta librería) se puede ver bastante bien cómo se monta este sistema(es exactamente igual a como lo monta el segundo grupo):

web: http://www.stum.de/…url-shortening-service…-project/

LilURL

Esta librería es del 2 grupo; aunque hace una encriptación un tanto rara y bastante enrevesada. Hace una encriptación con caracteres alfabéticos en minúscula.

Lo curioso es que no usa el indice incremental; es él mismo quien va creando la secuencia de identificadores. Para que os hagáis una idea de cómo funciona, este es su código para generar el identificador:

$id = $this->get_next_id($this->get_last_id());

Como podéis ver, genera el identificador a partir del último. Esto resultaría interesante si no fuese porque realiza una consulta a la base de datos para poder conocer el último identificador generado y a partir de ahí genera el siguiente.

web: http://lilurl.sourceforge.net/

Loolu

Este pertenece al segundo grupo y sin lugar a duda, para mi, es la mejor manera de encriptar la URL. Aquí directamente se descompone el número en una base (64) y se representa con caracteres numéricos, alfabéticos con minúsculas y mayúsculas. El algoritmo es más que sencillo (está en python):

codeset  = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
base = 62 # len(codeset)
#....
def encode(self, id):
        hash = ""
        while (id > 0):
            hash = self.codeset[int(id % self.base)] + hash
            id = math.floor(id / self.base)
        return hash

Poco más que añadir a lo genial que es esta solución, simple y eficaz.

web: http://code.google.com/p/loolu/

LessN

Esta librería pertenece al tercer grupo; encripta la URL utilizando un CheckSum (de PHP y Mysql) y lo usa como identificador. Código que realiza la encriptación:

$checksum 		= sprintf('%u', crc32($url));
$escaped_url 	= function_exists('mysql_real_escape_string') ? mysql_real_escape_string($url) : mysql_escape_string($url);
//...
mysql_query('INSERT INTO `'.DB_PREFIX.'urls` SET `url`="'.$escaped_url.'", `checksum`='.$checksum);

nota: Cómo podéis ver es muy importante escapar las URL, ya que corremos el peligro de que nos pongan javascript en la url y puede llegar a ejecutarse en el navegador.

web: http://www.shauninman.com/archive/2009/08/17/less_n

Resumen

En este tipo de servicios, es muy importante tener muy en cuenta el rendimiento de nuestra aplicación, ya que una mala arquitectura te puede consumir demasiados recursos. Es por eso que personalmente me quedo con el algoritmo de Loolu que me parece de lo más sencillo y eficiente.

  • Leo G

    hola, vi un link, que tenias sobre un árbol, que estaba bueno soy novato en esto, quería saber si me podes indicar como reemplas el array para qe se cargue con una consulta.