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缩略图生成程式(需要GD库支持)
Mar 06 PHP
php实现的在线人员函数库
Apr 09 PHP
php中base64_decode与base64_encode加密解密函数实例
Nov 24 PHP
非常实用的php验证码类
May 15 PHP
在Laravel框架里实现发送邮件实例(邮箱验证)
May 20 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
Jul 10 PHP
基于PHP常用文件函数和目录函数整理
Aug 17 PHP
利用PHP判断是手机移动端还是PC端访问的函数示例
Dec 14 PHP
php使用curl模拟浏览器表单上传文件或者图片的方法
Nov 10 PHP
Yii2.0框架模型多表关联查询示例
Jul 18 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
Sep 10 PHP
PHP7 新增常量
Mar 09 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
一个简单的MySQL数据浏览器
2006/10/09 PHP
phpfans留言版用到的数据操作类和分页类
2007/01/04 PHP
php中is_null,empty,isset,unset 的区别详细介绍
2013/04/28 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
2016/03/10 PHP
如何用PHP做到页面注册审核
2017/03/02 PHP
python进程与线程小结实例分析
2018/11/11 PHP
IE下写xml文件的两种方式(fso/saveAs)
2013/08/05 Javascript
JavaScript限定复选框的选择个数示例代码
2013/08/25 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
JavaScript 控制字体大小设置的方法
2016/11/23 Javascript
Vue2几种常见开局方式详解
2017/09/09 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
clipboard在vue中的使用的方法示例
2018/10/19 Javascript
Vue中用props给data赋初始值遇到的问题解决
2018/11/27 Javascript
Vue如何使用混合Mixins和插件开发详解
2020/02/05 Javascript
JavaScript实现简单的弹窗效果
2020/05/19 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
[57:22]2018DOTA2亚洲邀请赛 4.7总决赛 LGD vs Mineski 第五场
2018/04/10 DOTA
Python删除指定目录下过期文件的2个脚本分享
2014/04/10 Python
python中stdout输出不缓存的设置方法
2014/05/29 Python
Python的ORM框架中SQLAlchemy库的查询操作的教程
2015/04/25 Python
python编写简单爬虫资料汇总
2016/03/22 Python
浅析Python中的赋值和深浅拷贝
2017/08/15 Python
python中virtualenvwrapper安装与使用
2018/05/20 Python
pyinstaller打包单个exe后无法执行错误的解决方法
2019/06/21 Python
python爬虫数据保存到mongoDB的实例方法
2020/07/28 Python
柒牌官方商城:中国男装优秀品牌
2017/06/30 全球购物
班级入场式解说词
2014/02/01 职场文书
销售总经理岗位职责
2014/03/15 职场文书
《东方明珠》教学反思
2014/04/20 职场文书
销售个人求职信范文
2014/04/28 职场文书
保外就医申请书范文
2015/08/06 职场文书
小学秋季运动会通讯稿
2015/11/25 职场文书
初中地理教学反思
2016/02/19 职场文书
为什么 Nginx 比 Apache 更牛逼
2021/03/31 Servers
SQL Server数据库的三种创建方法汇总
2023/05/08 MySQL