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

本文实例讲述了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程序设计有所帮助。

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xml json 比较_JSON和XML:它们如何比较?

xml json 比较JSON和XML&#xff1a;它们如何比较&#xff1f; JSON和XML是两种人类可读的文本格式&#xff0c;多年来已成为竞争对手。 XML的目的是通过可选使用模式来存储和定义文档和数据。 JSON几乎完全相反-序列化格式的要求非常简单&#xff0c;可以放在信用卡背面。 但是…

HashSet的学习

文章目录HashSet特点常用方法增删改查性能分析LinkedHashSetHashSet 特点 1.不允许存储重复的元素 2.只允许存储一个 null 3.没有索引值&#xff0c;所以不能使用普通的 for 循环遍历集合元素&#xff0c;也没有与索引值相关的方法 4.是一个无序的集合&#xff0c;存储元素和…

为什么引入TSS

【0】README text description from orange’s implemention of a os and for complete code ,please visit https://github.com/pacosonTang/Orange-s-OS/blob/master/p62.asm. 【1】 回忆——关于堆栈 通过调用门进行有特权级变换的转移——理论篇 &#xff08;1&#xff…

mysql 天数减1_mysql 日期操作 增减天数、时间转换、时间戳

MySQL datediff(date1,date2)&#xff1a;两个日期相减 date1 - date2&#xff0c;返回天数。select datediff(2008-08-08, 2008-08-01); -- 7select datediff(2008-08-01, 2008-08-08); -- -7一、MySQL 获得当前日期时间 函数1.1 获得当前日期时间(date time)函数&#xff1a…

jdk open jdk_JDK 14的迹象开始出现

jdk open jdkJDK 13当前处于Rampdown阶段1 &#xff08;RDP 1&#xff09;&#xff0c;计划在一周多一点的时间&#xff08;2019年7月18日&#xff09;进入Rampdown阶段2 &#xff08;RDP 2&#xff09;&#xff0c;并暂定于2019年9月17日正式上市。当然&#xff0c;这意味着是…

Java集合ArrayList的学习

文章目录特点常用的方法集合迭代器特点 1.集合只能存放对象&#xff0c;可以存储重复元素&#xff0c;不允许存储 null 2.集合存放的对象类型可以不一致 3.集合的长度可以改变&#xff0c;初始大小10&#xff0c;最大容量 Integer.MAX_VALUE - 8&#xff0c;满时扩容&#xff…

知识复习(LDT+TSS+GATE+INTERRUPT)

【1】README 1.0&#xff09;由于实现进程的切换任务&#xff0c;其功能涉及到 LDT TSS &#xff27;ATE INTERRUPT&#xff1b;下面我们对这些内容进行复习&#xff1b; 1.1&#xff09; source code from orange’s implemention of a os . 【2】知识复习&#xff08;LDTT…

arduinopn532模块_树莓派使用libnfc驱动ITEAD NFC PN532模块

libnfc是首个遵循GNU(自由工程项目)通用公共许可证针对所有人都完全免费的低级别NFC软件开发包和编程应用程序接口。它提供了完整的透明度且免费供大家使用。该库目前支持调制ISO / IEC14443 A和B&#xff0c;FeliCa&#xff0c;Jewel/Topaz标签及数据交换协议(P2P)作为目标和启…

jakarta ee_Jakarta EE的拟议命名空间

jakarta ee免责声明&#xff1a;这是我的个人观点&#xff0c;并不代表雇主的观点。 到目前为止&#xff0c;由于从Oracle迁移到Eclipse Foundation&#xff0c;每个人都知道我们需要将所有javax软件包名称重命名为其他名称。 &#xff08;供参考&#xff0c;请参阅附录A&…

类ResourceBundle详解

类 ResourceBundle 的核心作用就是用来加载指定的属性资源文件&#xff08;.properties 文件&#xff09;&#xff0c;其作用有点类似类 Properties。 public void test() {Locale locale new Locale("zh", "CN");// 根据指定的语言环境和基名加载资源文件…

Makefile浅尝

【0】README makefile定义&#xff1a; 一个工程中的源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定&#xff0c;哪些文件需要一先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&a…

java类验证和装载顺序_Java类的加载顺序

1、有继承关系的加载顺序关于关键字static&#xff0c;大家 都知道它是静态的&#xff0c;相当于一个全局变量&#xff0c;也就是这个属性或者方法是可以通过类来访问&#xff0c;当class文件被加载进内存&#xff0c;开始初始化的时候&#xff0c;被static修饰的变量或者方法即…

java代码识别_识别Java中的代码气味

java代码识别作为软件开发人员&#xff0c;我们不仅要编写有效的代码&#xff0c;而且还要编写可维护的代码&#xff0c;这是我们的责任。 Martin Fowler在他的《重构&#xff1a;改进现有代码的设计》中将代码气味定义为&#xff1a; 通常对应于系统中更深层问题的表面指示 …

关于Java父子类继承的问题

1.子类无法继承父类的构造器 2.子类可以继承父类所有的变量和方法&#xff0c;父类私有的方法和变量也被继承到子类中&#xff0c;只是不可见而已&#xff0c;子类无法直接调用和访问。在子类对象中存储着父类中所有的变量的数据以及父类所有方法的引用地址。 3.被重写的父类方…

git连接到github(SSH无密码登陆)

【0】README 0.1&#xff09;本文旨在尝试在linux环境下免密码连接到github&#xff0c;并进行push pull projects in github by git commands。0.1&#xff09; 对ssh免密码登录有不熟悉的童鞋&#xff0c;please visit http://blog.csdn.net/pacosonswjtu/article/details/…

excel柱状图堆叠图显示总和_excel堆积柱形图显示百分比 在Excel堆积图中显示百分比标签的方法...

excel堆积柱形图显示百分比 在Excel堆积图中显示百分比标签的方法&#xff0c;前天刚学习了一个excel的新技术&#xff0c;叫“excel堆积柱形图显示百分比”授课老师对我们说&#xff0c;这一技术的专业全称为“excel堆积柱形图显示百分比 在Excel堆积图中显示百分比标签的方法…

java命令模式_Java中的命令设计模式

java命令模式在本教程中&#xff0c;我们将学习命令模式&#xff0c;这是一种重要的行为设计模式。 它具有一些重要的应用程序&#xff0c;例如在文本编辑器中实现撤消/重做功能。 在命令设计模式中&#xff0c;有一个命令对象位于发送方和接收方对象之间。 发送者对象可以创建…

抽象类与接口的区别

文章目录抽象类的理解接口的理解区别分析演示案例总结参考抽象类的理解 动物就是对某类事物的普遍性、共同性进行抽取后得到的用来反映这类事物本质的概念。 动物被定义为靠摄取有机物(植物、动物或微生物&#xff09;来获得营养而不能完成无机物到有机物转化过程的能够对环境…

浅尝硬盘分区表

【0】README 0.1&#xff09; text description from orange’s implemention of a os&#xff1b; 0.2&#xff09; there are a number of analysis and attention proves to be essence of this page, I think; 0.3&#xff09;Conclusion about hd partition table C1…

openjdk-7支持版本_长期支持对OpenJDK意味着什么?

openjdk-7支持版本Bruno Borges最近在推特上发布了一个有关OpenJDK的长期支持&#xff08;LTS&#xff09;的问题&#xff0c;这表明对它的真正含义仍有一些困惑。 在此博客文章中&#xff0c;我将解释不同部分如何组合在一起。 那么……谁说或在哪里说“ #OpenJDK 11”是LTS&…