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 相关文章推荐
最小化数据传输――在客户端存储数据
Oct 09 PHP
php 生成自动创建文件夹并上传文件的示例代码
Mar 07 PHP
php中操作memcached缓存进行增删改查数据的实现代码
Aug 15 PHP
php比较相似字符串的方法
Jun 05 PHP
浅谈PDO的rowCount函数
Jun 18 PHP
php通过会话控制实现身份验证实例
Oct 18 PHP
form自动提交实例讲解
Jul 10 PHP
利用Homestead快速运行一个Laravel项目的方法详解
Nov 14 PHP
PHP Class SoapClient not found解决方法
Jan 20 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
Feb 07 PHP
详解PHP队列的实现
Mar 14 PHP
使用PHP反射机制来构造&quot;CREATE TABLE&quot;的sql语句
Mar 21 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中实现图片的锐化
2006/10/09 PHP
PHP中return 和 exit 、break和contiue 区别与用法
2012/04/09 PHP
PHP中new static() 和 new self() 的区别介绍
2015/01/09 PHP
分享ThinkPHP3.2中关联查询解决思路
2015/09/20 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
jQuery中append、insertBefore、after与insertAfter的简单用法与注意事项
2020/04/04 Javascript
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
jquery animate实现鼠标放上去显示离开隐藏效果
2013/07/21 Javascript
浅谈JS闭包中的循环绑定处理程序
2014/11/09 Javascript
Jquery弹出层插件ThickBox的使用方法
2014/12/09 Javascript
jQuery复制表单元素附源码分享效果演示
2015/09/30 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
JS二分查找算法详解
2017/11/01 Javascript
Angular2开发环境搭建教程之VS Code
2017/12/15 Javascript
浅谈super-vuex使用体验
2018/06/25 Javascript
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
vue-i18n结合Element-ui的配置方法
2019/05/20 Javascript
[06:07]刀塔密之二:攻之吾命受之吾幸
2014/07/03 DOTA
Python中字符串对齐方法介绍
2015/05/21 Python
Python语言进阶知识点总结
2019/05/28 Python
使用Python计算玩彩票赢钱概率
2019/06/26 Python
Django CSRF跨站请求伪造防护过程解析
2019/07/31 Python
Django框架安装方法图文详解
2019/11/04 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
2021/02/01 Python
伦敦眼门票在线预订:London Eye
2018/05/31 全球购物
Araks官网:纽约内衣品牌
2020/10/15 全球购物
关键字final的用法
2013/10/02 面试题
教师实习自我鉴定
2013/12/14 职场文书
求职自我推荐信
2014/06/25 职场文书
健康状况证明书
2014/11/26 职场文书
活动总结模板大全
2015/05/11 职场文书
HTML5 新增内容和 API详解
2021/11/17 HTML / CSS