短链接就不说了, 大家已经都清楚了, 如下所示就是短链接:
新浪微博 http://t.cn/SVpONM
腾讯微博 http://url.cn/302yor
Yun.io http://d.yun.io/PNri2v
短链接的好处: 1 内容需要; 2 用户友好; 3 便于管理
如何实现呢, 大概有三个步骤:
1 定义一个 URL 映射算法, 可以将长的 URL 映射成短字符串;
2 使用一个存储 (数据库? NoSQL?) 来存储完成的映射;
3 实现自己的 URL 映射算法;
一般来说, 第三步是我们比较头疼的, 如何将一个长的 URL 字符串, 映射成一个较短的字符串呢我总结了三种办法:
普通实现
我想以前大家学习过十进制和二进制的互相转换, 或者十进制和十六进制的互相转换, 那么为了更短, 我们可以使用 62 进制, 对于一个数字 ID 进行转码, 转换成一个短字符串
这种做法的缺点是没有办法保证所有链接都是固定的位数的长度, 而且在高并发的情况下, 如何保证能够快速分发是个问题
具体实现方法:
代码如下:
- /**
- * 利用 62 进制对数字 ID 进行短链接编码, 缺点不能保证每个短链接是固定长度
- *
- * @author wanshiqiang
- * @param integer $integer
- * @param string $base
- */
- private function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)
- {
- $length = strlen($base);
- while($integer> $length - 1)
- {
- $out = $base[fmod($integer, $length)] . $out;
- $integer = floor( $integer / $length );
- }
- return $base[$integer] . $out;
- }
- /**
- * 对 62 进制编码的短链接进行解码
- *
- * @author wangshiqiang
- * @param string $string
- * @param string $base
- */
- private function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)
- {
- $length = strlen($base);
- $size = strlen($string) - 1;
- $string = str_split($string);
- $out = strpos($base, array_pop($string));
- foreach($string as $i => $char)
- {
- $out += strpos($base, $char) * pow($length, $size - $i);
- }
- return $out;
- }
文艺实现
算法描述: 使用 6 个字符来表示短链接, 我们使用 ASCII 字符中的'a'-'z','0'-'5', 共计 32 个字符做为集合每个字符有 32 种状态, 六个字符就可以表示 32^6(1073741824), 那么如何得到这六个字符, 描述如下:
对传入的长 URL 进行 Md5, 得到一个 32 位的字符串, 这个字符串变化很多, 是 16 的 32 次方, 基本上可以保证唯一性将这 32 位分成四份, 每一份 8 个字符, 这时机率变成了 16 的 8 次方, 是 4294967296, 这个数字碰撞的机率也比较小啦, 关键是后面的一次处理我们将这个 8 位的字符认为是 16 进制整数, 也就是 1*('0x'.$val), 然后取 0-30 位, 每 5 个一组, 算出他的整数值, 然后映射到我们准备的 32 个字符中, 最后就能够得到一个 6 位的短链接地址
PHP 实现如下:
代码如下:
- function shorten( $long_url )
- {
- $base32 = "abcdefghijklmnopqrstuvwxyz012345";
- $hex = md5( $long_url );
- $hexLen = strlen( $hex );
- $subHexLen = $hexLen / 8;
- $output = array();
- for( $i = 0; $i <$subHexLen; $i++ )
- {
- $subHex = substr( $hex, $i * 8, 8 );
- $subHex = 0x3FFFFFFF & ( 1 * ('0x' . $subHex ) );
- $out = '';
- for( $j = 0; $j < 6; $j++ )
- {
- $val = 0x0000001F & $int;
- $out .= $base32[$val];
- $int = $int>> 5;
- }
- $output[] = $out;
- }
- return $output;
- }
二逼实现
下面这个函数使用了纯随机的方式来生成一个短链接, 虽然我们可以通过查询操作来确保不重复使用短链接, 可是... 这样真的靠谱吗~~
代码如下:
- function random($length, $pool = '') {
- $random = '';
- if (empty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .=
- '23456789'; }
- srand ((double)microtime()*1000000);
- for($i = 0; $i < $length; $i++) { $random .=
- substr($pool,(rand()%(strlen ($pool))), 1); }
- return $random;
- }
- Yours.org
- Free PHP URL Shorten script that kicks ass
- PHP Short Url Algorithm Implementation
- Implement your own short URL
来源: https://www.php1.cn/detail/php-94fb37f27d.html