基于Python实现Hash算法
作者:紧到长不胖 发布时间:2023-09-21 17:29:58
1 前言
Simhash
的算法简单的来说就是,从海量文本中快速搜索和已知simhash相差小于k位的simhash集合,这里每个文本都可以用一个simhash值来代表,一个simhash有64bit,相似的文本,64bit也相似,论文中k的经验值为3。该方法的缺点如优点一样明显,主要有两点,对于短文本,k值很敏感;另一个是由于算法是以空间换时间,系统内存吃不消。
2 一般hash算法
最简单的hash算法是用取余的方式,根据hash地址存放数据,这需要提供键值对(Key-value)Key是地址,value是存放的数据
2.1 算法逻辑
输入存放数据,并建立(Key-value)对象
通过取余数的方式 公式
:哈希地址,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地址指向不同的服务器访问地址,为不同的服务器上的数据库存取提供了便利
来源:https://blog.csdn.net/weixin_43213884/article/details/123563099


猜你喜欢
- 本文实例讲述了php简单获取复选框值的方法。分享给大家供大家参考,具体如下:html:<form id="form1&quo
- 介绍Django是一个Web框架——一套用于帮助开发交互式网站的工具。Django能够响应网页请求,还能让我们更轻松地读写数据库、管理用户等
- 前言:Python 自带了很多的内置函数,极大地方便了我们的开发,下面就来挑几个内置函数,看看底层是怎么实现的。内置函数位于 Python/
- 刚刚上网搜了一下如何用python统计列表中不同元素的数量,发现很少,找了半天。我自己来写一种方法。代码如下list=[1,1,2,2,3]
- 300来行python代码实现简易版学生成绩管理系统,供大家参考,具体内容如下使用链表来实现class Node(object): def
- 【写在前面】这真的是太那个什么了不管怎么说 做过的东西做个笔记总是好的花一点点时间做笔记不然如果哪一天要重新做了 或者哪一天要汇报工作 都不
- 本文实例讲述了python多线程使用方法。分享给大家供大家参考,具体如下:threading 模块支持守护线程, 其工作方式是:守护线程一般
- 目录 一,抓取情况描述二,网页分析三,程序编写 一,抓取情况描述1.抓取的页面需要登陆,以公司网页为例,登陆网址http
- mysql数据通过data文件恢复mysql磁盘文件被损坏,无法启动,能看到data文件,在没有备份的话如何复原?情景1:知道数据库中的表结
- 我就废话不多说了,大家还是直接看代码吧~</pre><pre code_snippet_id="1947416&
- 最近,找到了一种新的pycharm激活方法,支持Jetbrains全家桶,比如 idea、pychram、WebStorm等等,没得zhil
- 这是我为了学习tkinter用python 写的一个下载m3u8视频的小程序,程序使用了多线程下载,下载后自动合并成一个视频文件,方便播放。
- 假设现在有如下N条记录 表明叫book id author title 1 aaa AAA 2 bbb BBB 3 ccc CCC 4 dd
- 本文简单介绍如何使用 Python 的 pyautogui 模块实现鼠标的自动移动以及键盘的自行输入. 该模块不是 Python 自带的,
- 1. 简介本文将介绍 Go 语言中的 sync.Cond 并发原语,包括 sync.Cond的基本使用方法、实现原理、使用注意事项以及常见的
- 概念第一步:计算一个梯度 Ix,Iy第二步:整合矩阵,计算特征值第三步:比较特征值的大小第四步: 非极大值抑制,把真正的角点留下来,角点周围
- <% &nbs
- 原理请查看前面几篇文章。1、数据源SH600519.csv 是用 tushare 模块下载的 SH600519 贵州茅台的日 k 线数据,本
- 接着python里面的xlrd模块详解(一)中我们我们来举一个实例:我们来举一个从Excel中读取账号和密码的例子并调用:&diam
- 0 前言安装:pip install pypiwin32 1 Excel的APIimport win32com.client as win3