将长链接转化成短链接

今天遇到了一个将长链接转化成短链接的问题,苦思没有得到较好的无重复url的方案,遂到网上查了一个。

算法大致如下:

1)将长网址md5生成32位签名串,分为4段, 每段8个字节;

2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;

3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;

4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;

实现如下:

1. 正则表达式匹配url,验证该长链接是否为正常url,最初写了一个preg_match pattern, /^http:\/\/([\w-]+\.)+[\w-]+([\w-.\/?%&=]*)?$/ 。这种可以直接匹配http开头的url,后来想了一下好像url不止http协议的吧,改成了/^(http|https|ftp):\/\/([\w-]+\.)+[\w-]+([\w-.\/?%&=]*)?$/。这样可以匹配ftp协议了。当然协议还有很多,就不一一列述了。代码实现:

const URL_PATTERN = "|^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$|";

const URL_PATTERN_MUTI = /^(http|https|ftp):\/\/([\w-]+\.)+[\w-]+([\w-.\/?%&=]*)?$/;

$url = 'http://www.jb51.net/tools/zhengze.html';

$result = test_pregmatch_url($url);

function  test_pregmatch_url($url) {
        preg_match(self::URL_PATTERN_MUTI, $url, $match);
        return array_shift($match);
}    

2. 实现上述url转换短链算法。

function shorturl($input) {
  $base32 = array (
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
    'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
    'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
    'y', 'z', '0', '1', '2', '3', '4', '5'
    );

  $hex = md5($input);
  $hexLen = strlen($hex);
  $subHexLen = $hexLen / 8;
  $output = array();

  for ($i = 0; $i < $subHexLen; $i++) {
    $subHex = substr ($hex, $i * 8, 8);
    $int = 0x3FFFFFFF & (1 * ('0x'.$subHex));
    $out = '';

    for ($j = 0; $j < 6; $j++) {
      $val = 0x0000001F & $int;
      $out .= $base32[$val];
      $int = $int >> 5;
    }

    $output[] = $out;
  }

  return $output;
}

3. 将生成短链作为redis的key,长链作为value存在redis中。同步到对应数据库表中。

4. 这样当浏览器通过该短链访问时,可从对应存储中得到长链然后parse_url提供服务。

 

 
posted @ 2012-11-17 23:55  风之子_2012  阅读(2931)  评论(0编辑  收藏  举报