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网页显示各种语法错误
Sep 23 PHP
PHP echo,print,printf,sprintf函数之间的区别与用法详解
Nov 27 PHP
PHP访问Google Search API的方法
Mar 05 PHP
php使用simplexml_load_file加载XML文件并显示XML的方法
Mar 19 PHP
PHP判断一个字符串是否是回文字符串的方法
Mar 23 PHP
PHP中异常处理的一些方法整理
Jul 03 PHP
PHP和C#可共用的可逆加密算法详解
Oct 26 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
基于swoole实现多人聊天室
Jun 14 PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 PHP
解决laravel中日志权限莫名变成了root的问题
Oct 17 PHP
PHP与Web页面交互操作实例分析
Jun 02 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 session_start()关于Cannot send session cache limiter - headers already sent错误解决方法
2009/11/27 PHP
PHP转换IP地址到真实地址的方法详解
2013/06/09 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
php修改上传图片尺寸的方法
2015/04/14 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
php基于闭包实现函数的自调用(递归)实例分析
2016/11/11 PHP
PHP addAttribute()函数讲解
2019/02/03 PHP
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
JQUERY 获取IFrame中对象及获取其父窗口中对象示例
2013/08/19 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
jQuery实现文本框输入同步的方法
2015/06/20 Javascript
JavaScript 基础函数_深入剖析变量和作用域
2016/05/18 Javascript
总结AngularJS开发者最常犯的十个错误
2016/08/31 Javascript
vue-router跳转页面的方法
2017/02/09 Javascript
JS实现PC手机端和嵌入式滑动拼图验证码三种效果
2017/02/15 Javascript
jQuery树插件zTree使用方法详解
2017/05/02 jQuery
微信网页登录逻辑与实现方法
2019/04/29 Javascript
js回到页面指定位置的三种方式
2020/12/17 Javascript
Element-ui upload上传文件限制的解决方法
2021/01/22 Javascript
爬山算法简介和Python实现实例
2014/04/26 Python
解读Python中degrees()方法的使用
2015/05/18 Python
详解Django中六个常用的自定义装饰器
2018/07/04 Python
如何通过50行Python代码获取公众号全部文章
2019/07/12 Python
python使用原始套接字发送二层包(链路层帧)的方法
2019/07/22 Python
python3获取当前目录的实现方法
2019/07/29 Python
python实现俄罗斯方块小游戏
2020/04/24 Python
Django中和时区相关的安全问题详解
2020/10/12 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
HTML5 的新的表单元素(datalist/keygen/output)使用介绍
2013/07/19 HTML / CSS
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
北京泡泡网网络有限公司.net面试题
2012/07/17 面试题
元旦晚会上单位领导演讲稿
2014/01/05 职场文书
初三物理教学反思
2014/01/21 职场文书
欠条样本
2015/07/03 职场文书
win10拖拽文件时崩溃怎么解决?win10文件不能拖拽问题解决方法
2022/08/14 数码科技