1、Hash,与运算,映射,位移
MD5来Hash;32位分成四份进行与运算,每份保留30位,这30位分成6段, 每5个一组,算出其整数值,然后映射到准备的62个字符中, 依次进行获得一个6位的短链接地址。
<?php
function shorturl($longurl)
{
//hash私钥(被改进部分)
//$shorturlkey = '2rcwzfsefw';
//生成随机字串符(ASCII)(改进部分)
//$shorturlkey = '';
//for ($i=0; $i <= 15; $i++) {
// $shorturlkey .= chr(mt_rand(33,63));
// $shorturlkey .= chr(mt_rand(64,126));
//}
//映射字符(被改进部分)
$base62 = 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');
//对映射字符乱序(改进部分)
//shuffle($base62);
// 利用md5算法方式生成hash值
//$urlhex = hash('md5', $shorturlkey.$longurl);
$urlhex = md5($shorturlkey.$longurl);
//计算hash后的长度
$urlhexlen = strlen($urlhex);
//长度除以8
$subHexLen = $urlhexlen / 8 ;
$output = array();
//处理过程
for ($i = 0; $i < $subHexLen; $i++)
{
// 将这32位分成四份,每一份8个字符,将其视作16进制串与0x3fffffff(30位1)与操作
$subHex = substr($urlhex, $i*8, 8);
$idx = 0x3FFFFFFF & (1 * ('0x' . $subHex));
$out = '';
// 这30位分成6段, 每5个一组,算出其整数值,然后映射到62个字符
for ($j = 0; $j < 6; $j++)
{
$val = 0x0000003D & $idx;
$out .= $base62[$val];
$idx = $idx >> 5;
}
$output[$i] = $out;
}
//输出生成的四个当中的随机一个(改进部分)
//return $output[mt_rand(0,3)];
//(被改进部分)
return $output;
}
?>
不足
经过实际测试(每次生成5K),原始代码重复率很大,一开始可能只有0.000x%,到后来可能上升到0x%。。。
改进
对映射的字符进行随机排位,最后输出的时候只随机输出4个当中的一个,碰撞几率同下
2、纯随机
<?php
function shorturl_rand(){
//循环随机,如果要修改位数,直接修改循环条件中的$i小于(n-1)即可
for ($i=0,$b=''; $i <5 ; $i++) {
//随机当前位为数字还是小写字母以及大写字母
$a = mt_rand(0,2);
//选择器
switch ($a) {
case 0:
//随机数字
$b .= chr(mt_rand(48,57));
break;
case 1:
//随机小写字母
$b .= chr(mt_rand(97,122));
break;
case 2:
//随机大写字母
$b .= chr(mt_rand(65,90));
break;
break;
default:
break;
}
}
return $b ;
}
?>
纯随机,碰撞几率最低,性能消耗可能是同类中最低。
本文共 359 个字数,平均阅读时长 ≈ 1分钟
貌似好复杂