PHP

分享两个短链算法

Jonty
2014-01-01 / 1 评论 / 97 阅读 / 正在检测是否收录...

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 &amp; (1 * ('0x' . $subHex));

        $out = '';
        // 这30位分成6段, 每5个一组,算出其整数值,然后映射到62个字符
        for ($j = 0; $j < 6; $j++)
        {
            $val = 0x0000003D &amp; $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分钟
0

打赏

海报

正在生成.....

评论 (1)

取消
  1. 头像
    Pang Lv.1
    中国四川省 ·Windows 7 · Google Chrome
    沙发

    貌似好复杂

    回复 删除 垃圾