短いURL生成変換

2373 ワード

主なロジック:
1.L=26+26+10+10=62の長さの大文字と小文字、データを含む文字列LSを決定する
2,L**N個の整数を初期化して、一つのシーケンスpushとしてredisに入れる
3,1つの長いURLを変換する必要がある時、先に以上のシーケンスの中からランダムにpopして1つの整数Iを出します
4,整数Iに対して型を取る(除数L)、残りはLSの1文字に対応して、型を取った後に更にLで除算して整頓して、結果が0に等しい時型を取り除くことを停止して、さもなくば結果は型を取ることを継続します.
5,すべての剰余に対応するアルファベットを順番に並べて短い文字列SSを得る
6,長いURLのmd 5ハッシュ値をKEY,文字列SSをVALUEとしてredisに書き込む
7,文字列SSをKEY,長いURLをVALUEとしてredisに書き込む
8,接頭辞(短urlドメイン名)に文字列SSを付けて短URL結果として返す
9,ユーザが短いurlでアクセスすると,短いURLの文字列SSを取り出し,KEYとしてredisから長いURLを取り出し,長いURLをスキップする
注意:
redisのシーケンス番号がすぐに使用される場合は、スクリプトを書いていつでも監視でき、10%未満の場合は自動的に数を増やすことができます.使用済みの数字を保存してはいけません.
#encoding=utf-8
import string
import redis
import hashlib

LETTERS = string.digits + string.ascii_letters
LETTERS_NUM = len(LETTERS)
COUNTER_KEY = 'url:counter'

def init(rd,num):
    for i in xrange(LETTERS_NUM * num):
        rd.sadd('url:id:set',i)

#  urlid   url      
def get_url(urlid):
        result = []
        q = urlid/LETTERS_NUM
        r = urlid%LETTERS_NUM
        result.append(LETTERS[r])
        while q:
            r = q%LETTERS_NUM
            q = q/LETTERS_NUM
            result = [LETTERS[r]] + result
        return ''.join(result)

#   url   
def parse_url(rd, longurl):
    ret = longurl
    if (longurl.startswith("http://") or longurl.startswith("https://")) and len(longurl)>7: 
        m = hashlib.md5()
        m.update(longurl)
        urlkey = m.digest()
        old_param = rd.get(urlkey)
        if old_param:                 
            ret = old_param
        else:
            urlid = int(rd.spop('url:id:set'))
            param = get_url(urlid)
            rd.incr(COUNTER_KEY, 1)
            rd.set(param,longurl)
            rd.set(urlkey,param)
            ret = param    
    print "short url:",ret
    return ret

if __name__ == "__main__":
    url = "http://www.google.com/"
    rd = redis.Redis('127.0.0.1',6379,db=0)
    init(rd,3)
    parse_url(rd,url)