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开发文件系统实例讲解
Oct 09 PHP
php+jquery编码方面的一些心得(utf-8 gb2312)
Oct 12 PHP
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
Mar 07 PHP
解析PHP函数array_flip()在重复数组元素删除中的作用
Jun 27 PHP
php数组合并的二种方法
Mar 21 PHP
PHP中应该避免使用同名变量(拆分临时变量)
Apr 03 PHP
CI框架使用composer安装的依赖包步骤与方法分析
Nov 21 PHP
php 基础函数
Feb 10 PHP
PHP格式化显示时间date()函数代码
Oct 03 PHP
php使用curl模拟浏览器表单上传文件或者图片的方法
Nov 10 PHP
PHP大文件切割上传功能实例分析
Jul 01 PHP
php多进程中的阻塞与非阻塞操作实例分析
Mar 04 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关于array_multisort多维数组排序的使用说明
2011/01/04 PHP
PHP文件读取功能的应用实例
2015/05/08 PHP
php实现可运算的验证码
2015/11/10 PHP
PHP实现的登录,注册及密码修改功能分析
2016/11/25 PHP
PHP实现简单登录界面
2019/10/23 PHP
php提高脚本性能的4个技巧
2020/08/18 PHP
Laravel配合jwt使用的方法实例
2020/10/25 PHP
一个加载js文件的小脚本
2007/06/28 Javascript
js监听表单value的修改同步问题,跨浏览器支持
2009/12/31 Javascript
js日期相关函数总结分享
2013/10/15 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
使用jQuery在对象中缓存选择器的简单方法
2015/06/30 Javascript
jquery实现可自动判断位置的弹出层效果代码
2015/10/12 Javascript
使用jQuery处理AJAX请求的基础学习教程
2016/05/10 Javascript
详解微信小程序开发之下拉刷新 上拉加载
2016/11/24 Javascript
基于JavaScript实现的折半查找算法示例
2017/04/14 Javascript
AngularJs 常用的过滤器
2017/05/15 Javascript
JS鼠标滚动分页效果示例
2017/07/05 Javascript
JS+canvas绘制的动态机械表动画效果
2017/09/12 Javascript
vue路由跳转时判断用户是否登录功能的实现
2017/10/26 Javascript
JavaScript模块详解
2017/12/18 Javascript
Vue中props的使用详解
2018/06/15 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
2020/07/28 Javascript
vue项目页面嵌入代码块vue-prism-editor的实现
2020/10/30 Javascript
[45:06]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第二场 11.28
2020/12/02 DOTA
python3使用pyqt5制作一个超简单浏览器的实例
2017/10/19 Python
python3使用flask编写注册post接口的方法
2018/12/28 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
Python 读取有公式cell的结果内容实例方法
2020/02/17 Python
python matplotlib包图像配色方案分享
2020/03/14 Python
HTML5文档结构标签
2017/04/21 HTML / CSS
GafasWorld哥伦比亚:网上购买眼镜
2017/11/28 全球购物
管理失职检讨书
2014/02/12 职场文书
中层领导干部群众路线对照检查材料思想汇报
2014/10/02 职场文书
休学证明范本
2015/06/19 职场文书
2016暑期政治学习心得体会
2016/01/23 职场文书