主要逻辑:
1, 确定一个包括大小写字母、数据的字符串LS,长度为 L = 26+26+10 = 62
2, 初始化L**N个整数,并作为一个序列push到redis里
3, 当需要转换一个长URL时,先从以上的序列中随机pop出一个整数I
4, 对整数I取模(除数为L),余数对应到LS的一个字母,取完模后再除以L取整,当结果等于0时停止除模,否则结果继续取模。
5, 将所有余数对应的字母按顺序排列得到一个简短的字符串SS
6, 将长URL的md5哈希值作为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-8import stringimport redisimport hashlibLETTERS = string.digits + string.ascii_lettersLETTERS_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 retif __name__ == "__main__": url = "http://www.google.com/" rd = redis.Redis('127.0.0.1',6379,db=0) init(rd,3) parse_url(rd,url)
登录后复制
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2281577.html