+ -
当前位置:首页 → 问答吧 → 短网址生成(高进制数字转换)

短网址生成(高进制数字转换)

时间:2010-07-03

来源:互联网

江湖上流传着各种各样的短网址“算法”但无不能逃脱高重复性和低效率的厄运。
这里不免俗的也说一下直接由自增序列来生产短网址的方法。

使用六十二进制将十进制数字变“短”。
例如数据库中第 56800235583 条信息,对应的短网址后缀可以是 ZZZZZZ 。
下面是存储示例:

id 自增序列/自增编号
url 目标链接
*suffix* 短网址后缀 (并不需要存储在数据库内)
  1. +------------+-----------------------+---------+
  2. |id          | url                   | *suffix*|
  3. +------------+-----------------------+---------+
  4. |123456      | http://zoeey.com/     | w7e     |
  5. +------------+-----------------------+---------+
  6. |123457      | http://www.zoeey.com/ | w7f     |
  7. +------------+-----------------------+---------+
  8. |56800235582 | http://zoeey.org/     | ZZZZZY  |
  9. +------------+-----------------------+---------+
  10. |56800235583 | http://www.zoeey.org/ | ZZZZZZ  |
  11. +------------+-----------------------+---------+
复制代码
短网址使用流程:

           
  • 提交网址存储后获取其编号 如:123456
            
  • 用dec2Any将编号转换为62进制,并拼接网址 如:http://go.to/w7e
            
  • 用户访问到 http://go.to/w7e 时,提取短网址后缀 w7e
            
  • 用any2Dec将短网址后缀转换为10进制,得到链接编号 如:123456
            
  • 使用编号查询链接,并进行跳转


下面是进制转换所需要的源码:
  1. /*
  2. * MoXie ([email protected]) 2010-6-30 17:53:57
  3. *
  4. * Copyright © 2008-2010 Zoeey.Org . All rights are reserved.
  5. * Code license: Apache License  Version 2.0
  6. * http://www.apache.org/licenses/LICENSE-2.0.txt
  7. */
  8. error_reporting(E_ALL);

  9. /**
  10. * 返回一字符串,十进制 number 以 radix 进制的表示。
  11. * @param dec       需要转换的数字
  12. * @param toRadix    输出进制。当不在转换范围内时,此参数会被设定为 2,以便及时发现。
  13. * @return    指定输出进制的数字
  14. */
  15. function dec2Any($dec, $toRadix) {
  16.     $MIN_RADIX = 2;
  17.     $MAX_RADIX = 62;
  18.     $num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  19.     if ($toRadix < $MIN_RADIX || $toRadix > $MAX_RADIX) {
  20.         $toRadix = 2;
  21.     }
  22.     if ($toRadix == 10) {
  23.         return $dec;
  24.     }
  25.     // -Long.MIN_VALUE 转换为 2 进制时长度为65
  26.     $buf = array();
  27.     $charPos = 64;
  28.     $isNegative = $dec < 0; //(bccomp($dec, 0) < 0);
  29.     if (!$isNegative) {
  30.         $dec = -$dec; // bcsub(0, $dec);
  31.     }

  32.     while (bccomp($dec, -$toRadix) <= 0) {
  33.         $buf[$charPos--] = $num62[-bcmod($dec, $toRadix)];
  34.         $dec = bcdiv($dec, $toRadix);
  35.     }
  36.     $buf[$charPos] = $num62[-$dec];
  37.     if ($isNegative) {
  38.         $buf[--$charPos] = '-';
  39.     }
  40.     $_any = '';
  41.     for ($i = $charPos; $i < 65; $i++) {
  42.         $_any .= $buf[$i];
  43.     }
  44.     return $_any;
  45. }

  46. /**
  47. * 返回一字符串,包含 number 以 10 进制的表示。<br />
  48. * fromBase 只能在 2 和 62 之间(包括 2 和 62)。
  49. * @param number    输入数字
  50. * @param fromRadix    输入进制
  51. * @return  十进制数字
  52. */
  53. function any2Dec($number, $fromRadix) {
  54.     $num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  55.     $dec = 0;
  56.     $digitValue = 0;
  57.     $len = strlen($number) - 1;
  58.     for ($t = 0; $t <= $len; $t++) {
  59.         $digitValue = strpos($num62, $number[$t]);
  60.         $dec = bcadd(bcmul($dec, $fromRadix), $digitValue);
  61.     }
  62.     return $dec;
  63. }

  64. $sol = '<br />' . PHP_EOL;
  65. echo dec2Any('56800235583', 62), $sol; // ZZZZZZ
  66. echo any2Dec('ZZZZZZ', 62), $sol; // 56800235583
  67. echo dec2Any('123456', 62), $sol; // w7e
  68. echo any2Dec('w7e', 62), $sol; // 123456
复制代码
参考资料:
Zoeey/NumberHelper.java

原帖:
http://www.zoeey.com/2010/06/30/short-url-radix-convert/

作者: SysTem128   发布时间: 2010-07-03

作者: qxhy123   发布时间: 2010-07-03

嗯... 不错...

作者: 如惈   发布时间: 2010-07-03

不错。

作者: muzifeng   发布时间: 2010-07-03

思路不同就省下了很多的功夫

作者: qxhy123   发布时间: 2010-07-03

自增的缺点是没有离散性

作者: TankMe   发布时间: 2010-07-03

原来那函数得自己写啊

作者: fkj   发布时间: 2010-07-03

不错啊!学习了

作者: hack7755   发布时间: 2010-07-28