五位的大概有3000万种可能 七位有几百亿可能,虽然重复概率很低,大流量商用建议继续优化
<?php
/**
* 短链接类
*/
class urlManager {
//前缀
public static $prefix = 'weiyixi';
//后缀
public static $suffix = 'ixiyiwei';
//
public static $index = 0 ;
//32个基础字符
public static $base_key = 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", "-", "_");
/**
* 创建短链接 - 5 位
*
网上摘录方法:
1)将长网址md5生成32位签名串,分为4段, 每段8个字节;
2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;
3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;
4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;
*
*/
public static function create5($long_url,$k=0){
$out='';
if($k>3) return;
$hex = md5(self::$prefix.$long_url.self::$suffix);
$subhex = substr($hex, $k * 8, 8);
$int = hexdec($subhex);
for($i=0; $i<5; $i++)
{
$index = $int & 0x3f;
//最后一位如果是“-”, 则替换为a,避免部分手机上链接显示错误的问题
if($i == 4 && $index == 62)
$index = 0;
$out .= self::$base_key[$index];
$int = $int >> 6;
}
return $out;
}
/**
* 创建短链接 - 7 位
*
网上摘录方法:
1)将长网址md5生成32位签名串,分为3段, 每段42位;
2)这42位分成7段, 每6位的数字作为字母表的索引取得特定字符, 依次进行获得7位字符串;
*
*/
public static function create7($long_url,$k=0){
$out='';
$hex = md5(self::$prefix.$long_url.self::$suffix);
switch($k)
{
case 0:
$subhex = substr($hex, 21, 11); //最后42位
break;
case 1:
$subhex = substr($hex, 11, 11); //中间42位
break;
case 2:
$subhex = substr($hex, 0, 11); //最前面的42位,最前2位抛弃
break;
default:
return;
}
$int = hexdec($subhex);
if($k==1)
$int = $int >> 2; //此处最后2位已被$k=0时所用,故抛弃
for($i=0; $i<7; $i++)
{
$index = $int & 0x3f;
//最后一位如果是“-”, 则替换为a,避免部分手机上链接显示错误的问题
if($i == 6 && $index == 62)
$index = 0;
$out .= self::$base_key[$index];
$int = $int >> 6;
}
return $out;
}
}