Python实现短网址ShortUrl的Hash运算实例讲解


Posted in Python onAugust 10, 2015

本文实例讲述了Python实现短网址ShortUrl的Hash运算方法。分享给大家供大家参考。具体如下:

shorturl实现常见的做法都是将原始Url存储到数据库,由数据库返回一个对应ID。

以下要实现的是不用数据库支持就对原始URL进行shorturl hash。说到这里我们很容易想到MD5,固定长度,冲突概率小,但是32个字符,太长?我们以MD5为基础,将其字符缩短,同时要保证一定数量范围内hash不会冲突。

我们分成两个步骤来实现。

第一步算法:

① 将长网址用md5算法生成32位签名串,分为4段,,每段8个字符;
② 对这4段循环处理,取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作,超过30位的忽略处理;
③ 将每段得到的这30位又分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;
④ 这样一个md5字符串可以获得4个6位串,取里面的任意一个就可作为这个长url的短url地址。
(出现重复的几率大约是n/(32^6) 也就是n/1,073,741,824,其中n是数据库中记录的条数)

我们就得到了4个6位串,可是选哪个作为最终的hash结果呢,随机选肯定是不行的,同样的url两次hash就会得出不同的结果。接下来根据原始url的特征进行选择,并且将hash冲突的可能性控制在同一个domain内:

第二步算法:

①从原始url中提取域名,提取数字(最多后6位);
②将所得的数字与4取模,根据所得的余数决定从第一步算法中得到的4个shorturl中选取哪一个;
③从域名中提取特征串:一级域名中的第一个字符和后面二个辅音(如果辅音不足2个取任意前两个);
④域名特征串和选定的shorturl拼接成9位字符为最终的shorturl;
(后两个步骤是将冲突控制在一个domain内)

ShortUrl.py

#encoding:utf-8
__author__ = 'James Lau'
import hashlib
import re
def __original_shorturl(url):
  '''
  算法:
  ① 将长网址用md5算法生成32位签名串,分为4段,,每段8个字符;
  ② 对这4段循环处理,取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作,超过30位的忽略处理;
  ③ 将每段得到的这30位又分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;
  ④ 这样一个md5字符串可以获得4个6位串,取里面的任意一个就可作为这个长url的短url地址。
  (出现重复的几率大约是n/(32^6) 也就是n/1,073,741,824,其中n是数据库中记录的条数)
  '''
  base32 = ['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'
  ]
  m = hashlib.md5()
  m.update(url)
  hexStr = m.hexdigest()
  hexStrLen = len(hexStr)
  subHexLen = hexStrLen / 8
  output = []
  for i in range(0,subHexLen):
    subHex = '0x'+hexStr[i*8:(i+1)*8]
    res = 0x3FFFFFFF & int(subHex,16)
    out = ''
    for j in range(6):
      val = 0x0000001F & res
      out += (base32[val])
      res = res >> 5
    output.append(out)
  return output
def shorturl(url):
  '''
  算法:
  ①从原始url中提取域名,提取数字(最多后6位);
  ②将所得的数字与4取模,根据所得的余数决定从第一步算法中得到的4个shorturl中选取哪一个;
  ③从域名中提取特征串:一级域名中的第一个字符和后面二个辅音(如果辅音不足2个取任意前两个);
  ④域名特征串和选定的shorturl拼接成9位字符为最终的shorturl;
  (后两个步骤是将冲突控制在一个domain内)
  '''
  match_full_domain_regex = re.compile(u'^https?:\/\/(([a-zA-Z0-9_\-\.]+[a-zA-Z0-9_\-]+\.[a-zA-Z]+)|([a-zA-Z0-9_\-]+\.[a-zA-Z]+)).*$')
  match_full_domain = match_full_domain_regex.match(url)
  if match_full_domain is not None:
    full_domain = match_full_domain.group(1)
  else:
    return None
  not_numeric_regex = re.compile(u'[^\d]+')
  numeric_string = not_numeric_regex.sub(r'',url)
  if numeric_string is None or numeric_string=='':
    numeric_string = '0'
  else:
    numeric_string = numeric_string[-6:]
  domainArr = full_domain.split('.')
  domain = domainArr[1] if len(domainArr)==3 else domainArr[0]
  vowels = 'aeiou0-9'
  if len(domain)<=3:
    prefix = domain
  else:
    prefix = re.compile(u'[%s]+'%vowels).sub(r'',domain[1:])
    prefix = '%s%s'%(domain[0],prefix[:2]) if len(prefix)>=2 else domain[0:3]
  t_shorturl = __original_shorturl(url)
  t_choose = int(numeric_string)%4
  result = '%s%s'%(prefix,t_shorturl[t_choose])
  return result

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python break语句详解
Mar 11 Python
python用来获得图片exif信息的库实例分析
Mar 16 Python
python实现的简单FTP上传下载文件实例
Jun 30 Python
Python入门_浅谈字符串的分片与索引、字符串的方法
May 16 Python
Python实现图片转字符画的示例代码
Aug 21 Python
Python实现替换文件中指定内容的方法
Mar 19 Python
python 读取dicom文件,生成info.txt和raw文件的方法
Jan 24 Python
Python进阶之全面解读高级特性之切片
Feb 19 Python
如何运行.ipynb文件的图文讲解
Jun 27 Python
Python 合并拼接字符串的方法
Jul 28 Python
让你相见恨晚的十个Python骚操作
Nov 18 Python
pandas将list数据拆分成行或列的实现
Dec 13 Python
python实现web方式logview的方法
Aug 10 #Python
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
Aug 10 #Python
python用10行代码实现对黄色图片的检测功能
Aug 10 #Python
详解Python中dict与set的使用
Aug 10 #Python
分析并输出Python代码依赖的库的实现代码
Aug 09 #Python
python根据京东商品url获取产品价格
Aug 09 #Python
python制作一个桌面便签软件
Aug 09 #Python
You might like
PHP执行速率优化技巧小结
2008/03/15 PHP
php+iframe实现隐藏无刷新上传文件
2012/02/10 PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
php中用加号与用array_merge合并数组的区别深入分析
2013/06/03 PHP
jquery 实现表单验证功能代码(简洁)
2012/07/03 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
jQuery找出网页上最高元素的方法
2015/03/20 Javascript
js判断是否为空和typeof的用法(详解)
2016/10/07 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
React中的render何时执行过程
2018/04/13 Javascript
详解小程序原生使用ES7 async/await语法
2018/08/06 Javascript
python正则匹配抓取豆瓣电影链接和评论代码分享
2013/12/27 Python
python里大整数相乘相关技巧指南
2014/09/12 Python
Python编程实现数学运算求一元二次方程的实根算法示例
2017/04/02 Python
Pandas标记删除重复记录的方法
2018/04/08 Python
python模块smtplib学习
2018/05/22 Python
用Python徒手撸一个股票回测框架搭建【推荐】
2019/08/05 Python
Python 50行爬虫抓取并处理图灵书目过程详解
2019/09/20 Python
Python变量作用域LEGB用法解析
2020/02/04 Python
python实现俄罗斯方块小游戏
2020/04/24 Python
基于css3实现漂亮便签样式
2013/03/18 HTML / CSS
CSS3实现头像旋转效果
2017/03/13 HTML / CSS
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
高三自我鉴定怎么写
2013/10/19 职场文书
《草虫的村落》教学反思
2014/02/16 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
公司应聘求职信
2014/06/21 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
镇党政领导班子民主生活会思想汇报
2014/10/11 职场文书
公务员党的群众路线教育实践活动学习心得体会
2014/10/30 职场文书
企业介绍信范文
2015/01/30 职场文书
党校学习个人总结
2015/02/15 职场文书
2016年教师寒假学习心得体会
2015/10/09 职场文书
小程序后台PHP版本部署运行 LNMP+WNMP
2021/04/01 Servers
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL