微博短链接算法php版本实现代码


Posted in PHP onSeptember 15, 2012

思路:
1)将长网址md5生成32位签名串,分为4段, 每段8个字节;
2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;
3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;
4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;
下面是PHP代码:

function shorturl($url='', $prefix='', $suffix='') { 
$base = array ( 
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 
'y', 'z', '0', '1', '2', '3', '4', '5'); 
$hex = md5($prefix.$url.$suffix); 
$hexLen = strlen($hex); 
$subHexLen = $hexLen / 8; 
$output = array(); 
for ($i = 0; $i < $subHexLen; $i++) { 
$subHex = substr ($hex, $i * 8, 8); 
$int = 0x3FFFFFFF & (1 * ('0x'.$subHex)); 
$out = ''; 
for ($j = 0; $j < 6; $j++) { 
$val = 0x0000001F & $int; 
$out .= $base[$val]; 
$int = $int >> 5; 
} 
$output[] = $out; 
} 
return $output; 
} 
$urls = shorturl('https://3water.com/'); 
var_dump($urls);

结果
array(4) { 
[0]=> 
string(6) "alms1l" 
[1]=> 
string(6) "2ipmby" 
[2]=> 
string(6) "avo1hu" 
[3]=> 
string(6) "fdlban" 
}

另外一个版本:
function shorturl($url='', $prefix='', $suffix='') { 
$base = array( 
"a","b","c","d","e","f","g","h", 
"i","j","k","l","m","n","o","p", 
"q","r","s","t","u","v","w","x", 
"y","z","0","1","2","3","4","5", 
"6","7","8","9","A","B","C","D", 
"E","F","G","H","I","J","K","L", 
"M","N","O","P","Q","R","S","T", 
"U","V","W","X","Y","Z"); 
$hex = md5($prefix.$url.$suffix); 
$hexLen = strlen($hex); 
$subHexLen = $hexLen / 8; 
$output = array(); 
for ($i = 0; $i < $subHexLen; $i++) { 
$subHex = substr ($hex, $i * 8, 8); 
$int = 0x3FFFFFFF & (1 * ('0x'.$subHex)); 
$out = ''; 
for ($j = 0; $j < 6; $j++) { 
$val = 0x0000003D & $int; 
$out .= $base[$val]; 
$int = $int >> 5; 
} 
$output[] = $out; 
} 
return $output; 
}

结果:
array(4) { 
[0] => 
string(6) "6jmMVj" 
[1] => 
string(6) "2EnIby" 
[2] => 
string(6) "6vIVfu" 
[3] => 
string(6) "B7Fb6n" 
}

但是升级版本碰撞率反而更高了,不知道为什么。
测试碰撞的测试代码:
$result = array(); 
$repeats= array(); 
$loop = 20000; 
for($i=0;$i<$loop;$i++){ 
$url = 'https://3water.com/?id='.$i; 
$shorta = shorturl($url); 
$short = $shorta[0]; 
if(in_array($short, $result)){ 
$repeats[] = $short; 
} 
$result[] = $short; 
} 
$result = array(); 
for($i=0;$i<$loop;$i++){ 
$url = 'https://3water.com/?id='.$i; 
$shorta = shorturl($url); 
$short = $shorta[0]; 
if(in_array($short, $repeats)){ 
$result[$short][] = $url; 
} 
} 
var_dump($repeats); 
var_dump($result);

结果:
array(8) { 
[0] => 
string(6) "3eQBzq" 
[1] => 
string(6) "uQFnay" 
[2] => 
string(6) "qEZbIv" 
[3] => 
string(6) "fMneYf" 
[4] => 
string(6) "FJj6Fr" 
[5] => 
string(6) "3Eviym" 
[6] => 
string(6) "j2mmuy" 
[7] => 
string(6) "jyQfIv" 
} 
array(8) { 
'jyQfIv' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=1640" 
[1] => 
string(27) "https://3water.com/?id=18661" 
} 
'fMneYf' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=2072" 
[1] => 
string(26) "https://3water.com/?id=8480" 
} 
'3eQBzq' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=4145" 
[1] => 
string(26) "https://3water.com/?id=4273" 
} 
'j2mmuy' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=7131" 
[1] => 
string(27) "https://3water.com/?id=17898" 
} 
'qEZbIv' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=7320" 
[1] => 
string(26) "https://3water.com/?id=8134" 
} 
'uQFnay' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=7347" 
[1] => 
string(26) "https://3water.com/?id=7962" 
} 
'FJj6Fr' => 
array(2) { 
[0] => 
string(26) "https://3water.com/?id=8628" 
[1] => 
string(26) "https://3water.com/?id=9031" 
} 
'3Eviym' => 
array(2) { 
[0] => 
string(27) "https://3water.com/?id=11175" 
[1] => 
string(27) "https://3water.com/?id=14437" 
} 
}
PHP 相关文章推荐
用PHP调用数据库的存贮过程
Oct 09 PHP
PHP的加密方式及原理
Jun 14 PHP
PHP 基于Yii框架中使用smarty模板的方法详解
Jun 13 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
Jun 27 PHP
PHP判断指定时间段的2个方法
Mar 14 PHP
PHP的反射类ReflectionClass、ReflectionMethod使用实例
Aug 05 PHP
一款简单实用的php操作mysql数据库类
Dec 08 PHP
PHP ajax 异步执行不等待执行结果的处理方法
May 27 PHP
分享PHP源码批量抓取远程网页图片并保存到本地的实现方法
Dec 01 PHP
PHP使用curl模拟post上传及接收文件的方法
Mar 04 PHP
基于PHP常用文件函数和目录函数整理
Aug 17 PHP
thinkPHP框架实现的短信接口验证码功能示例
Jun 20 PHP
PHP优于Node.js的五大理由分享
Sep 15 #PHP
PHP的autoload机制的实现解析
Sep 15 #PHP
PHP中数组合并的两种方法及区别介绍
Sep 14 #PHP
PHP合并两个数组的两种方式的异同
Sep 14 #PHP
PHP数据流应用的一个简单实例
Sep 14 #PHP
分享一下贝贝成长进度的php代码
Sep 14 #PHP
PHP 之Section与Cookie使用总结
Sep 14 #PHP
You might like
PHP.MVC的模板标签系统(五)
2006/09/05 PHP
迅速确定php多维数组的深度的方法
2014/01/07 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
PHP连接access数据库
2015/03/27 PHP
thinkPHP+PHPExcel实现读取文件日期的方法(含时分秒)
2016/07/07 PHP
php实现批量修改文件名称的方法
2016/07/23 PHP
laravel 中某一字段自增、自减的例子
2019/10/11 PHP
jquery中常用的函数和属性详细解析
2014/03/07 Javascript
nodejs事件的监听与触发的理解分析
2015/02/12 NodeJs
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
vue.js移动端tab组件的封装实践实例
2017/06/30 Javascript
iscroll动态加载数据完美解决方法
2017/07/18 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
浅谈JS 数字和字符串之间相互转化的纠纷
2017/10/20 Javascript
对类Vue的MVVM前端库的实现代码
2018/09/07 Javascript
vue+php实现的微博留言功能示例
2019/03/16 Javascript
[01:05]主宰至宝剑心之遗
2017/03/16 DOTA
Windows下为Python安装Matplotlib模块
2015/11/06 Python
Python Requests安装与简单运用
2016/04/07 Python
Flask框架的学习指南之用户登录管理
2016/11/20 Python
Python与人工神经网络:使用神经网络识别手写图像介绍
2017/12/19 Python
wxpython布局的实现方法
2019/11/01 Python
修改Pandas的行或列的名字(重命名)
2019/12/18 Python
Python2及Python3如何实现兼容切换
2020/09/01 Python
python中使用.py配置文件的方法详解
2020/11/23 Python
.NET remoting的两种通道是什么
2016/05/31 面试题
大学生自我鉴定
2013/12/08 职场文书
应届毕业生自我鉴定范文
2013/12/27 职场文书
教师节倡议书
2014/08/30 职场文书
2014年旅游局法制宣传日活动总结
2014/11/01 职场文书
2014普法依法治理工作总结
2014/12/18 职场文书
2015年母亲节寄语
2015/03/23 职场文书
小学校长开学致辞
2015/07/29 职场文书
2016年春季运动会广播稿
2015/08/19 职场文书
Java由浅入深通关抽象类与接口(上篇)
2022/04/26 Java/Android
阿里云服务器Ubuntu 20.04上安装Odoo 15
2022/05/20 Servers