`

How to code a URL shortener?

 
阅读更多

How do you design URL shortener service?

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, len = str.length(); i < len; i++ ) {
            num = num * BASE + ALPHABET.indexOf( str.charAt(i) ); 
        }

        return num;
    }   
}

 

算法原理

算法一

1)将长网址md5生成32位签名串,分为4段, 每段8个字节;

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

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

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

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

 

算法二

a-zA-Z0-9 这64位取6位组合,可产生500多亿个组合数量.把数字和字符组合做一定的映射,就可以产生唯一的字符串,如第62个组合就是aaaaa9,第63个组合就是aaaaba,再利用洗牌算法,把原字符串打乱后保存,那么对应位置的组合字符串就会是无序的组合。

把长网址存入数据库,取返回的id,找出对应的字符串,例如返回ID为1,那么对应上面的字符串组合就是bbb,同理 ID为2时,字符串组合为bba,依次类推,直至到达64种组合后才会出现重复的可能,所以如果用上面的62个字符,任意取6个字符组合成字符串的话,你的数据存量达到500多亿后才会出现重复的可能。

具体参看这里彻底完善新浪微博接口和超短URL算法,算法四可以算作是此算法的一种实现,此算法一般不会重复,但是如果是统计的话,就有很大问题,特别是对域名相关的统计,就抓瞎了.

 

一个简单的python生成短链接的方法:

import hashlib  
 
def get_md5(s):  
    s = s.encode('utf8') if isinstance(s, unicode) else s  
    m = hashlib.md5()  
    m.update(s)  
    return m.hexdigest()  
 
code_map = (  
           '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'  
            )  
 
 
def get_hash_key(long_url):  
    hkeys = []  
    hex = get_md5(long_url)  
    for i in xrange(0, 1):  
        n = int(hex[i*8:(i+1)*8], 16)  
        v = []  
        e = 0  
        for j in xrange(0, 8):  
            x = 0x0000003D & n  
            e |= ((0x00000002 & n ) >> 1) << j  
            v.insert(0, code_map[x])  
            n = n >> 6  
        e |= n << 5  
        v.insert(0, code_map[e & 0x0000003D])  
        hkeys.append(''.join(v))  
    return hkeys[0]  
 
if __name__ == '__main__':  
    print get_hash_key('http://www.a2asdfasdfasfdbc.com')

 

References:

http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener

http://n00tc0d3r.blogspot.com/2013/09/big-data-tinyurl.html

http://iteye.blog.163.com/blog/static/1863080962012111223141936/

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics