如何编码URL缩短器?

我想创建一个URL shortener服务,您可以在输入字段中写入一个长URL,并且该服务将URL缩短为“ http://www.example.org/abcdef ”。

编辑:由于对这个主题的持续兴趣,我已经发布了一个有效的解决方案给GitHub,实现了JavaScript,PHP,Python和Java。 如果你喜欢,请加上你的解

除了“ abcdef ”之外,还可以有其他包含az, AZ and 0-9六个字符的其他字符串。 这使得56-570亿可能的字符串。

我的方法:

我有一个包含三列的数据库表:

  • ID,整数,自动递增
  • 长,字符串,用户输入的长URL
  • 短,字符串,缩短的网址(或只是六个字符)
  • 然后我会将长URL插入表格中。 然后,我会选择“ id ”的自动增量值并构建它的哈希值。 这个散列应该被插入为“ short ”。 但是我应该建立什么样的散列? 像MD5这样的哈希算法会创建太长的字符串。 我想,我不使用这些算法。 自建算法也可以工作。

    我的想法:

    对于“ http://www.google.de/ ”,我获得了自动增量ID 239472 。 然后我执行以下步骤:

    short = '';
    if divisible by 2, add "a"+the result to short
    if divisible by 3, add "b"+the result to short
    ... until I have divisors for a-z and A-Z.
    

    这可以重复,直到数字不再可以被整除。 你认为这是一个好方法吗? 你有更好的主意吗?


    我会继续你的“将数字转换为字符串”的方法。 然而,如果你的ID是一个素数并且大于52,你会意识到你提出的算法会失败。

    理论背景

    你需要一个双射函数f。 这是必要的,以便您可以为f(123)='abc'函数找到反函数g('abc')= 123。 意即:

  • 不得有x1,x2(x1≠x2),这将使f(x1)= f(x2),
  • 对于每一个你必须能够找到一个x使得f(x)= y。
  • 如何将ID转换为缩短的URL

  • 想想我们想用的字母表。 在你的情况是[a-zA-Z0-9] 。 它包含62个字母。
  • 采用自动生成的唯一数字键(例如,MySQL表的自动递增id )。

    对于这个例子,我将使用12510(125的基数为10)。

  • 现在您必须将12510转换为X62(基数62)。

    12510 = 2×621 + 1×620 = [2,1]

    这需要使用整数除法和模数。 一个伪代码示例:

    digits = []
    
    while num > 0
      remainder = modulo(num, 62)
      digits.push(remainder)
      num = divide(num, 62)
    
    digits = digits.reverse
    

    现在将索引2和1映射到您的字母表。 这就是你的映射(例如数组)的外观:

    0  → a
    1  → b
    ...
    25 → z
    ...
    52 → 0
    61 → 9
    

    使用2→c和1→b,您将收到cb62作为缩短的URL。

    http://shor.ty/cb
    
  • 如何将缩短的URL解析为初始ID

    反过来更容易。 您只需在字母表中进行反向查找。

  • e9a62将被解析为“字母表中的第4,第61和第0个字母”。

    e9a62 = [4,61,0] = 4×622 + 61×621 + 0×620 = 1915810

  • 现在用WHERE id = 19158找到你的数据库记录并做重定向。

  • 一些实现(由评论者提供)

  • 红宝石
  • 蟒蛇
  • CoffeeScript的
  • 哈斯克尔
  • Perl的
  • C#

  • 你为什么要使用散列?
    您只需使用简单的自动增量值转换为字母数字值即可。 您可以通过使用一些基本转换轻松完成此操作。 假设你的字符空间(AZ,az,0-9等)有40个字符,将ID转换为基数为40的数字,使用的字符是数字。


    public class UrlShortener {
        private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private static final int    BASE     = ALPHABET.length();
    
        public static String encode(int num) {
            StringBuilder sb = new StringBuilder();
            while ( num > 0 ) {
                sb.append( ALPHABET.charAt( num % BASE ) );
                num /= BASE;
            }
            return sb.reverse().toString();   
        }
    
        public static int decode(String str) {
            int num = 0;
            for ( int i = 0; i < str.length(); i++ )
                num = num * BASE + ALPHABET.indexOf(str.charAt(i));
            return num;
        }   
    }
    
    链接地址: http://www.djcxy.com/p/12599.html

    上一篇: How to code a URL shortener?

    下一篇: Bit popcount for large buffer, with Core 2 CPU (SSSE3)