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在Web开发领域的优势
Oct 09 PHP
使用 eAccelerator加速PHP代码的目的
Mar 16 PHP
php 修改zen-cart下单和付款流程以防止漏单
Mar 08 PHP
PHP中的错误处理、异常处理机制分析
May 07 PHP
ThinkPHP3.1数据CURD操作快速入门
Jun 19 PHP
在Nginx上部署ThinkPHP项目教程
Feb 02 PHP
php文件压缩之PHPZip类用法实例
Jun 18 PHP
PHP+MySQL实现无极限分类栏目的方法
Dec 23 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
May 17 PHP
php实现微信原生支付(扫码支付)功能
May 30 PHP
掌握PHP垃圾回收机制详解
Mar 13 PHP
Yii框架安装简明教程
May 15 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
escape unescape的php下的实现方法
2007/04/27 PHP
对于Laravel 5.5核心架构的深入理解
2018/02/22 PHP
文档对象模型DOM通俗讲解
2013/11/01 Javascript
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
2014/11/28 Javascript
JSON取值前判断
2014/12/23 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
js和jquery实现监听键盘事件示例代码
2020/06/24 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
利用JQuery直接调用asp.net后台的简单方法
2016/10/27 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
浅谈vue-router2路由参数注意的问题
2017/11/08 Javascript
vue项目优化之通过keep-alive数据缓存的方法
2017/12/11 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
关于angular 8.1使用过程中的一些记录
2020/11/25 Javascript
[01:02:10]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第一局
2016/02/26 DOTA
python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
2014/07/09 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
python实现简易云音乐播放器
2018/01/04 Python
对python Tkinter Text的用法详解
2018/10/11 Python
python学生信息管理系统(完整版)
2020/04/05 Python
python通过ffmgep从视频中抽帧的方法
2018/12/05 Python
对python特殊函数 __call__()的使用详解
2019/07/02 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
Python paramiko 模块浅谈与SSH主要功能模拟解析
2020/02/29 Python
Django-imagekit的使用详解
2020/07/06 Python
园林资料员岗位职责
2013/12/30 职场文书
缴纳养老保险的证明
2014/01/10 职场文书
《罗布泊,消逝的仙湖》教学反思
2014/03/01 职场文书
家教广告词
2014/03/19 职场文书
争先创优心得体会
2014/09/12 职场文书
2015年元旦标语大全
2014/12/09 职场文书
出国导师推荐信
2015/03/25 职场文书
个人售房合同协议书
2016/03/21 职场文书
JavaScript实现两个数组的交集
2022/03/25 Javascript