php 短链接算法

2012-10-04   来源:站长日记       编辑:沧海桑田   类别:PHP 教程    转载到:    发表评论

短链接的好处: . 内容需要 .用户友好 .便于管理 .利于SEO

php 短链接算法

短链接的好处
1、内容需要
2、用户友好
3、便于管理

短链接原理
实现短链接并不复杂,关键是短链接要够短,且需要唯一,
例子“d4zw8x”,6位,用户输入的同一个Url,返回唯一的短链接,用户在请求长的Url之后,先从数据库查找一下这个长Url是否存在,如果存在,就直接取出其对应的短代码,如果不存在,则生成短代码,与用户的长Url同时保存在数据库中。

短链接的样式
新浪微博 //t.cn/SVpONM
腾讯微博 //url.cn/302yor
短链接的实现

三个步骤
1、定义URL映射算法,将长URL映射成短字符串;
2、使用存储(数据库?NoSQL?)来存储完成的映射;
3、实现URL映射算法;
第三步比较难,如何将长URL字符串,映射成一个较短的字符串呢

三种办法

办法一 普通实现
十进制和二进制的互相转换,或者十进制和十六进制的互相转换,可以使用62进制,对于数字ID进行转码,转换成一个短字符串。
缺点是无法保证所有链接的长度都是固定的位数,在高并发的情况下,如何保证快速分发是个问题。
具体实现代码

function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
{
$length = strlen($base);
while($integer > $length - 1) {
$out = $base[fmod($integer, $length)] . $out;
$integer = floor( $integer / $length );
}
return $base[$integer] . $out;
}

function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)
{
$length = strlen($base);
$size = strlen($string) - 1;
$string = str_split($string);
$out = strpos($base, array_pop($string));
foreach($string as $i => $char){
$out += strpos($base, $char) * pow($length, $size - $i);
}
return $out;
}

办法二 文艺实现

算法描述
使用6个字符来表示短链接,使用ASCII字符中的'a'-'z','0'-'5',共计32个字符做为集合。
每个字符有32种状态,六个字符就可以表示32^6(1073741824),

如何得到这六个字符:
对传入的长URL进行Md5,得到一个32位的字符串,是16的32次方组合,基本上保证唯一性。
将这32位分成四份,每一份8个字符,机率变成了16的8次方,是4294967296,碰撞的机率比较小。
将这个8位的字符认为是16进制整数,也就是1*('0x'.$val),然后取0-30位,每5个一组,算出他的整数值,然后映射到32个字符中,最后就能够得到一个6位的短链接地址。
PHP实现代码:
function shorten( $long_url ) {
$base32 = "abcdefghijklmnopqrstuvwxyz012345";
$hex = md5( $long_url );
$hexLen = strlen( $hex );
$subHexLen = $hexLen / 8;
$output = array();
for( $i = 0; $i < $subHexLen; $i++ ) {
$subHex = substr( $hex, $i * 8, 8 );
$subHex = 0x3FFFFFFF & ( 1 * ('0x' . $subHex ) );
    $out = '';
for( $j = 0; $j < 6; $j++ ) {
$val = 0x0000001F & $int;
$out .= $base32[$val];
$int = $int >> 5;
}
$output[] = $out;
}
return $output;
}

办法三 二逼实现
使用纯随机的方式生成短链接,虽然通过查询操作来确保不重复使用短链接,不一定靠谱~~
实现代码:
function random($length, $pool = '') {
$random = '';
if (empty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .=
'23456789'; }
srand ((double)microtime()*1000000);
for($i = 0; $i < $length; $i++) { $random .=
substr($pool,(rand()%(strlen ($pool))), 1); }
return $random;
}

说明了怎么算,没说明为什么这么算,不算是好说明

14

0
14|0 | 鲜花 VS 砸蛋 | 61阅读 0评论
 
不想登录?直接点击发布即可作为游客留言。
昵称  邮箱 网站 验证码 = 1+1