php 短链接算法收集与分析


Posted in PHP onDecember 30, 2011

短链接就不说了,大家已经都清楚了,如下所示就是短链接:
新浪微博 http://t.cn/SVpONM
腾讯微博 http://url.cn/302yor
Yun.io http://d.yun.io/PNri2v
短链接的好处:1、内容需要;2、用户友好;3、便于管理。
如何实现呢,大概有三个步骤:
1、定义一个URL映射算法,可以将长的URL映射成短字符串;
2、使用一个存储(数据库?NoSQL?)来存储完成的映射;
3、实现自己的URL映射算法;
一般来说,第三步是我们比较头疼的,如何将一个长的URL字符串,映射成一个较短的字符串呢。我总结了三种办法:
普通实现
我想以前大家学习过十进制和二进制的互相转换,或者十进制和十六进制的互相转换,那么为了更短,我们可以使用62进制,对于一个数字ID进行转码,转换成一个短字符串。
这种做法的缺点是没有办法保证所有链接都是固定的位数的长度,而且在高并发的情况下,如何保证能够快速分发是个问题。
具体实现方法:

/** 
* 利用62进制对数字ID进行短链接编码,缺点不能保证每个短链接是固定长度 
* 
* @author wanshiqiang<wangshiqiang@360.cn> 
* @param integer $integer 
* @param string $base 
*/ 
private 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; 
} 
/** 
* 对62进制编码的短链接进行解码 
* 
* @author wangshiqiang<wangshiqiang@360.cn> 
* @param string $string 
* @param string $base 
*/ 
private 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; 
}

Technorati 标签: 短链接,Short Url,映射,哈希

参考资料:

1、微博短地址原理解析

2、微博短域名原理及作用

3、Yours.org

4、Free PHP URL Shorten script that kicks ass

5、PHP Short Url Algorithm Implementation

6、Implement your own short URL

7、短网址算法初步汇总

8、Short Url 实现方式

PHP 相关文章推荐
php数组声明、遍历、数组全局变量使用小结
Jun 05 PHP
深入HTTP响应状态码速查表的详解
Jun 07 PHP
使用php验证复选框有效性的示例
Nov 13 PHP
使用PHP备份MYSQL数据的多种方法
Jan 15 PHP
codeigniter自带数据库类使用方法说明
Mar 25 PHP
WordPress自定义时间显示格式
Mar 27 PHP
php以fastCGI的方式运行时文件系统权限问题及解决方法
May 11 PHP
PHP基于工厂模式实现的计算器实例
Jul 16 PHP
PHP实现原生态图片上传封装类方法
Nov 08 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
Apr 19 PHP
PHP join()函数用法与实例讲解
Mar 11 PHP
Swoole 5将移除自动添加Event::wait()特性详解
Jul 10 PHP
php的大小写敏感问题整理
Dec 29 #PHP
php读取mysql乱码,用set names XXX解决的原理分享
Dec 29 #PHP
php站内搜索并高亮显示关键字的实现代码
Dec 29 #PHP
PHP数组 为文章加关键字连接 文章内容自动加链接
Dec 29 #PHP
PHP防CC攻击实现代码
Dec 29 #PHP
php curl常见错误:SSL错误、bool(false)
Dec 28 #PHP
PHP+Ajax异步通讯实现用户名邮箱验证是否已注册( 2种方法实现)
Dec 28 #PHP
You might like
PHP常用特殊运算符号和函数总结(php新手入门必看)
2013/02/02 PHP
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
2014/10/14 PHP
PHP中时间加减函数strtotime用法分析
2017/04/26 PHP
js特殊字符转义介绍
2013/11/05 Javascript
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
javascript常用的方法分享
2015/07/01 Javascript
微信小程序 wx:key详细介绍
2016/10/28 Javascript
IntersectionObserver API 详解篇
2016/12/11 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
javascript实现Java中的Map对象功能的实例详解
2017/08/21 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
webstorm中配置nodejs环境及npm的实例
2018/05/15 NodeJs
JS构造一个html文本内容成文件流形式发送到后台
2018/07/31 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
vue select 获取value和lable操作
2020/08/28 Javascript
python中urllib模块用法实例详解
2014/11/19 Python
深入解析Python中的WSGI接口
2015/05/11 Python
python获得一个月有多少天的方法
2015/06/04 Python
在Python中的Django框架中进行字符串翻译
2015/07/27 Python
Python中绑定与未绑定的类方法用法分析
2016/04/29 Python
Python 读写文件和file对象的方法(推荐)
2016/09/12 Python
python 截取 取出一部分的字符串方法
2017/03/01 Python
python executemany的使用及注意事项
2017/03/13 Python
python机器学习之神经网络(三)
2017/12/20 Python
修改默认的pip版本为对应python2.7的方法
2018/11/06 Python
用django设置session过期时间的方法解析
2019/08/05 Python
详解Anaconda 的安装教程
2020/09/23 Python
在终端启动Python时报错的解决方案
2020/11/20 Python
python制作微博图片爬取工具
2021/01/16 Python
意大利和国际奢侈品牌购物网站:Suitnegozi.com
2021/01/15 全球购物
幼儿园运动会入场词
2014/02/10 职场文书
销售总经理岗位职责
2014/03/15 职场文书
2014年世界艾滋病日宣传活动总结
2014/11/18 职场文书
学校食品安全责任书
2015/01/29 职场文书
MongoDB orm框架的注意事项及简单使用
2021/06/20 MongoDB