五位的大概有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;
    }
}

标签: none

添加新评论