Python实现Hash算法


Posted in Python onMarch 18, 2022

1 前言

Simhash的算法简单的来说就是,从海量文本中快速搜索和已知simhash相差小于k位的simhash集合,这里每个文本都可以用一个simhash值来代表,一个simhash有64bit,相似的文本,64bit也相似,论文中k的经验值为3。该方法的缺点如优点一样明显,主要有两点,对于短文本,k值很敏感;另一个是由于算法是以空间换时间,系统内存吃不消。

2 一般hash算法

最简单的hash算法是用取余的方式,根据hash地址存放数据,这需要提供键值对(Key-value)Key是地址,value是存放的数据

2.1 算法逻辑

  • 输入存放数据,并建立(Key-value)对象
  • 通过取余数的方式 公式H = d H=d%nH=d H:哈希地址,d为数据,具有唯一性,n是样本总数
  • 把产生的哈希地址和对应数据存储到字典对象中

2.2 代码实现

# 1.需要记录的数据
records = [[1,50],[2,6],[3,47],[4,8],[5,9],[6,100]] # 数据键为日期,值为销售数量
# 2.定义存放的地址和数据
Sadress1 = {'192.168.1.1':1}
Sadress2 = {'192.168.1.2':2}
Sadress3 = {'192.168.1.3':4}
Sadress4 = {'192.168.1.4':6}

# 数据长度定义为
n = 20

# 判断哈希值,分段为0-1-2-4-6
for one in records:
    if one[0] % n <= Sadress1['192.168.1.1']: 
        Sadress1[one[0]]=one[1]
    elif one[0] % n <= Sadress2['192.168.1.2']:
        Sadress2[one[0]] = one[1]
    elif one[0] % n <= Sadress3['192.168.1.3']:
        Sadress3[one[0]] = one[1]
    elif one[0] % n <= Sadress4['192.168.1.4']:
        Sadress4[one[0]] = one[1]

print(Sadress1)
print(Sadress2)
print(Sadress3)
print(Sadress4)

2.3 总结

  • 这是最简单的Hash算法,还有MD5,SHAI,SHA2
  • 哈希地址冲突,问题主要考虑输入的唯一性取值方法
  • 在分布式计算中广泛应用

3 一致性hash算法

一致性Hash算法时为了防止单个节点宕机或者删除、新增,不会导致数据存储的混乱或者无法储存。一致性服务器要求对服务器地址通过哈希算法也进行映射方式确定输出地址,再加上对数据的哈希处理,一直哈希要实现两个算法过程。

3.1 算法逻辑

  • 输入数据,建立Key-value对象
  • 利用Hash算法产生哈希地址,建立键值字典
  • 输入服务器地址,利用哈希算法产生哈希地址
  • 数据通过地址和服务器地址,放到对应的范围内
  • 输出

3.2 代码实现

import hashlib # 导入带shal()哈希算法的函数库
class CHash(object):
    def __init__(self,nodes=None,v_num=2):# nodes节点存放节点地址,V-num一个节点对应,# 默认节点是为2
        self._v_num = v_num # 一个节点对应存放节点地址
        self._vNode_IP = {} # 用于虚拟节点的hash值与node的对应关系
        self._vNodeAdd = [] # 用于存放所有的虚拟节点的hash值,这里需要保持排序
        for node in nodes:
            self.addNode(node)
        print('\n虚拟节点哈希值升序排列:\n',self._vNodeAdd) # 对虚拟节点哈希地址进行从小到大排序

    # 1 建立虚拟节点环,顺序排列
    def addNode(self,node):
        for i in range(self._v_num):
            vNodeStr = '%s%s'%(node ,i) # 根据虚拟节点,为每个节点建立虚拟节点
            key = self._gen_key(vNodeStr) # 产生虚拟节点IP地址,服务器节点IP+i
            print('虚拟节点字符串',vNodeStr,'对应哈希值',key)
            self._vNode_IP[key] = node # 虚拟节点哈希地址为键,节点为IP地址为值
            self._vNodeAdd.append(key) # 对应虚拟节点哈希地址进行独立储存
            self._vNodeAdd.sort()
    # 2 删除退出节点地址及对应的虚拟地址
    def Del_Node(self,node): # 删除退出节点地址及对应的虚拟地址
        for i in range(self._v_num):
            vNodeStr = '%s%s'%(node,i)
            key = self._gen_key(vNodeStr)  # 产生虚拟节点的哈希地址
            del self._vNode_IP[key] # 通过哈希地址删除字典里面的虚拟节点信息
            self._vNodeAdd.remove(key) # 删除虚拟节点的哈希地址
    # 3 返回数据储存对应的服务器地址
    def dataNode(self,data):
        if self._vNodeAdd: # 虚拟节点的哈希地址列表不为空
            key = self._gen_key(data) # 产生业务数据对应的哈希地址
            print(data,'哈希地址',key)
            for node_key in self._vNodeAdd: # 获取虚拟节点的哈希地址
                if key <= node_key: # 业务数据的哈希地址<= 当前虚拟节点的哈希地址
                    return self._vNode_IP[node_key] # 返回当前虚拟节点哈希地址对应节点IP
            return self._vNodeAdd[self._vNodeAdd[0]] # 如果业务数据的哈希值超过所有节点的地址,则归入并返回第一个IP地址

        else:
            return None # 没有节点

    # 4 通过shal()产生哈希值
    @staticmethod # 装饰器
    def _gen_key(key_str):
        Hash_value = hashlib.sha1(key_str.encode('utf-8')).hexdigest()

        return Hash_value

# 测试
C_H = CHash(['192.168.1.1','192.168.1.2','192.168.1.3','192.168.1.4'])
data =['Mike','Margge','Maria']
print('\n正常情况下,存储数据时,归入的节点地址:')
print(data[0]+'存入的节点IP地址:',C_H.dataNode(data[0]))
print(data[1]+'存入的节点IP地址:',C_H.dataNode(data[1]))
print(data[2]+'存入的节点IP地址:',C_H.dataNode(data[2]))
# 192.168.2.1删除节点
print('\n192.168.1.2节点脱离分布式系统的情况:')
C_H.Del_Node('192.168.1.2') # 删除节点
print(data[0]+'存入的节点IP地址:',C_H.dataNode(data[0]))
print(data[1]+'存入的节点IP地址:',C_H.dataNode(data[1]))
print(data[2]+'存入的节点IP地址:',C_H.dataNode(data[2]))

虚拟节点字符串 192.168.1.10 对应哈希值 f53e4ef74ec8f55440f9caf382c5f63c4a39b4bc
虚拟节点字符串 192.168.1.11 对应哈希值 239b32be446b1288655b570c23ccb51633c03927
虚拟节点字符串 192.168.1.20 对应哈希值 c385b891af246719e1a60c715be2f375aeab0b5b
虚拟节点字符串 192.168.1.21 对应哈希值 0d12ca599dc0316beec6436bb3beb04e84fbe3e2
虚拟节点字符串 192.168.1.30 对应哈希值 265180387f1642217973f8cfda2ca6cc92d48e60
虚拟节点字符串 192.168.1.31 对应哈希值 d6dacbe137bec9a047737207a3a82036f8454362
虚拟节点字符串 192.168.1.40 对应哈希值 7497a9439524d6f044fc22a8723039e0c42bbac8
虚拟节点字符串 192.168.1.41 对应哈希值 89c78508a642956363ed40326fce4346d7889f88

虚拟节点哈希值升序排列:

 ['0d12ca599dc0316beec6436bb3beb04e84fbe3e2', '239b32be446b1288655b570c23ccb51633c03927', '265180387f1642217973f8cfda2ca6cc92d48e60', '7497a9439524d6f044fc22a8723039e0c42bbac8', '89c78508a642956363ed40326fce4346d7889f88', 'c385b891af246719e1a60c715be2f375aeab0b5b', 'd6dacbe137bec9a047737207a3a82036f8454362', 'f53e4ef74ec8f55440f9caf382c5f63c4a39b4bc']

正常情况下,存储数据时,归入的节点地址:

Mike 哈希地址 d6ac022931a66a2bcc244db91818ebec76ce5e18
Mike存入的节点IP地址: 192.168.1.3
Margge 哈希地址 ae5e1fda577bff360ed5da0b2804a1ff0b2a1675
Margge存入的节点IP地址: 192.168.1.2
Maria 哈希地址 3e182b1ea9376483a38614d916a0b666ef531b6d
Maria存入的节点IP地址: 192.168.1.4

192.168.1.2节点脱离分布式系统的情况:

Mike 哈希地址 d6ac022931a66a2bcc244db91818ebec76ce5e18
Mike存入的节点IP地址: 192.168.1.3
Margge 哈希地址 ae5e1fda577bff360ed5da0b2804a1ff0b2a1675
Margge存入的节点IP地址: 192.168.1.3
Maria 哈希地址 3e182b1ea9376483a38614d916a0b666ef531b6d
Maria存入的节点IP地址: 192.168.1.4

3.3 总结

  • 应用广泛,很好的解决了服务器宕机,节点删除等问题
  • IP地址指向不同的服务器访问地址,为不同的服务器上的数据库存取提供了便利

到此这篇关于基于Python实现Hash算法的文章就介绍到这了,更多相关Python实现Hash算法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python的Flask框架中使用日期和时间的教程
Apr 21 Python
利用Python中的pandas库对cdn日志进行分析详解
Mar 07 Python
Python 安装setuptools和pip工具操作方法(必看)
May 22 Python
Python实现base64编码的图片保存到本地功能示例
Jun 22 Python
Django CSRF跨站请求伪造防护过程解析
Jul 31 Python
python批量解压zip文件的方法
Aug 20 Python
使用Python脚本从文件读取数据代码实例
Jan 19 Python
pyqt5中动画的使用详解
Apr 01 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
Apr 03 Python
selenium.webdriver中add_argument方法常用参数表
Apr 08 Python
Pytest之测试命名规则的使用
Apr 16 Python
教你怎么用python爬取爱奇艺热门电影
May 20 Python
python实现会员信息管理系统(List)
Mar 18 #Python
Python实现归一化算法详情
Mar 18 #Python
python实现会员管理系统
Mar 18 #Python
Python内置数据类型中的集合详解
Python集合set()使用的方法详解
Mar 18 #Python
基于Python实现流星雨效果的绘制
Python中with上下文管理协议的作用及用法
Mar 18 #Python
You might like
Yii中srbac权限扩展模块工作原理与用法分析
2016/07/14 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
记录Yii2框架开发微信公众号遇到的问题及解决方法
2018/07/20 PHP
js的表单操作 简单计算器
2011/12/29 Javascript
利用NodeJS的子进程(child_process)调用系统命令的方法分享
2013/06/05 NodeJs
JavaScript设置获取和设置属性的方法
2015/03/04 Javascript
详解JavaScript中的客户端消息框架设计原理
2015/06/24 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
2015/07/29 Javascript
每天一篇javascript学习小结(基础知识)
2015/11/10 Javascript
JavaScript中的this机制
2016/01/30 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
详解vuex中mapState,mapGetters,mapMutations,mapActions的作用
2018/04/13 Javascript
基于JS实现带动画效果的流程进度条
2018/06/01 Javascript
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
Vue触发式全局组件构建的方法
2018/11/28 Javascript
vue2配置scss的方法步骤
2019/06/06 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
2020/01/18 Javascript
js与jquery获取input输入框中的值实例讲解
2020/02/27 jQuery
JavaScript之scrollTop、scrollHeight、offsetTop、offsetHeight等属性学习笔记
2020/07/15 Javascript
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
python2.7的编码问题与解决方法
2016/10/04 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
Django的HttpRequest和HttpResponse对象详解
2018/01/26 Python
python实现下载pop3邮件保存到本地
2018/06/19 Python
numpy:np.newaxis 实现将行向量转换成列向量
2019/11/30 Python
python查看矩阵的行列号以及维数方式
2020/05/22 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
2020/07/09 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
测试时代收集的软件测试面试题
2013/09/25 面试题
《寓言两则》教学反思
2014/02/27 职场文书
会计师事务所实习证明
2014/11/16 职场文书
初中优秀学生评语
2014/12/29 职场文书
vscode中使用npm安装babel的方法
2021/08/02 Javascript