交流学习

php生成url短链,算法优化

URL短网址生成算法原理

短网址(Short URL),是在形式上比较短的网址,通过映射关系跳转到原有的长网址。

通常用 php 或 python 转向,在Web 2.0的今天,不得不说,这是一个潮流。

自从twitter推出短网址(short url),继之国内各大微博跟风,google公开goo.gl使用API,短网址之风愈演愈烈。不得不说这是一个新兴又一大热门web2.0服务。

现整理一下,包括完整短网址网站,短网址生成原理,算法举例,以及优劣比较,同时还介绍几个phper个人实现的。

目前已经有许多类似服务,借助短网址您可以用简短的网址替代原来冗长的网址,让使用者可以更容易的分享链接。

例如:

短网址:http://t.cn/R3Krh36

长网址:https://blog.mimvp.com/article/25420.html

生成短网址:http://dwz.wailian.work/index.php

短网址服务,可能很多朋友都已经不再陌生,现在大部分微博、手机邮件提醒等地方已经有很多应用模式了,并占据了一定的市场。估计很多朋友现在也正在使用。

看过新浪的短连接服务,发现后面主要有6个字符串组成,于是第一个想到的就是原来公司写的一个游戏激活码规则,也就是下面的算法2,

1)26个大写字母 26小写字母,10个数字,随机生成6个然后插入数据库对应一个id,

2)短连接跳转的时候,根据字符串查询到对应id,即可实现相应的跳转

62种字符组合成6位字符,62^6=568亿个组合数量,重复的概率是很小的

短链接的好处

1、内容需要;2、用户友好;3、便于管理。

为什么要这样做的,原因我想有这样几点:

1)微博限制一条字数为140字,那么如果我们需要发一些连接上去,但是这个连接非常的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被允许的,所以短网址应运而生了。

2)短网址在项目里可以很好的对开放级URL进行管理。有一部分网址可以会涵盖暴力、广告等信息,这样我们可以通过用户的举报,完全管理这些链接不出现在我们的应用中。因为同样的URL通过加密算法之后,得到的地址是一样的。

3)我们可以对一系列的网址进行流量,点击等统计,挖掘出大多数用户的关注点,这样有利于我们对项目的后续工作更好的作出决策。

算法原理

算法一

1) 将长网址md5生成32位签名串,分为4段,每段8个字节; 52c06085 c4529732 5433e0c7 5b140565

2) 对这四段循环处理,取8个字节,将他看成16进制串与0x3fffffff(30位1)与操作,即前缀超过30位的字符串做忽略处理,直接舍弃掉了;

3) 这30位分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;

4) 总的md5串可以获得4个6位串,取里面的任意一个就可作为这个长url的短url地址;

这种算法,虽然会生成4个,但是仍然存在重复几率

/**
     * 指定数据生成唯一的字符串编码
     * @param $input
     * @param int $length
     * @return array
     */
    public static function shortString($input, $length = 8)
    {
        $base32 = array(
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
            'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9'

        );
        $key = 'xiangzhuan'; //自定义key值
        $hex = hash('md5', $input.$key);
        //$hex = md5($input);
        $hexLen = strlen($hex);

        $subHexLen = $hexLen / 8;   // 划分为4段,保留4组结果
        $resultArray = [];
        for ($i = 0; $i < $subHexLen; $i++) {
            $subHex = substr($hex, $i * 8, 8);         // 分成4段,每段取8位字符
              //$int = 0x3FFFFFFF & hexdec($subHex);
            $int = 0x3FFFFFFF & (1 * (filter_var(('0x' . $subHex), FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)));       // 8位字节与16进制取与操作
            $out = '';
            for ($j = 0; $j < $length; $j++) {
                $val = 0x0000001F & $int;   // 取0~31之间的整数
                $out .= $base32[$val];      // 从数组中获取对应字符
                $int = $int >> 5;
            }
            $resultArray[] = $out;
        }
        return $resultArray;
    }

转载自 https://blog.mimvp.com/article/25420.html

⬆️

暂无评论~~