哈希算法的应用


前言

哈希算法经常使用的场景是哈希表,也叫散列表。但是在很多 场景下,哈希算法都有广泛的应用


提示:以下是本篇文章正文内容

一、哈希算法是什么?

可以概括为:将任意长度的二进制串映射为固定长度的二进制串,这个映射规则就是哈希算法。

需要满足的要求:

  • 散列冲突概率要很小。
  • 算法的执行效率要高效,尤其针对长文本。
  • 单向性,不能通过给定的密文信息,推出明文。满足加密需求。
  • 对原数据的任意一点修改,所得哈希值都大不相同。
  • 抗强碰撞性

二、应用一:安全加密

常用于加密的哈希算法包括:MD5-消息摘要算法、SHA-安全散列算法、DES、AES算法。
MD5是常见的哈希算法,哈希值是固定的 128 位二进制串,能表示的数据是有限的,最多能表示 2^128 个数据。
因为我们的明文信息有无数种可能,远超过2^128,所以总会存在哈希冲突。
但是因为哈希值的范围很大,冲突的概率极低,所以相对来说还是很难破解的。
MD5散列冲突的概率要小于 1/2^128。

项目工程的应用
单纯使用MD5对密码进行加密已经没有很好的安全性,因为很多常见的密码都已经被计算出哈希值,随便搜就有很多MD5破解的网站,要想继续使用MD5,还需要对明文信息加入其它信息。
加盐加密:可以对要加密的数据再加入盐值,这个盐值可以是时间戳、随机数,等任何东西,将盐值和密码以一定规则组合在一起,再进行MD5加密,可以有效的保密信息。盐值也需要保存在数据库,比如密码加密后,要想登陆该账号,还需要当时的盐值。但是由于盐值和明文的组合方式有成千上万种,所以有很好的安全性。

三、应用二:唯一标识

场景:
如果要在海量的图库中,搜索一张图是否存在,我们不能单纯地用图片的元信息(比如图片名称)来比对,因为有可能存在名称相同但图片内容不同,或者名称不同图片内容相同的情况。

解决:

如果还想继续提高效率,我们可以把每个图片的唯一标识,和相应的图片文件在图库中的路径信息,都存储在散列表中。当要查看某个图片是不是在图库中的时候,我们先通过哈希算法(比如MD5)对这个图片取唯一标识,然后在散列表中查找是否存在这个唯一标识。通过这个唯一标识来判定图片是否在图库中,这样就可以减少很多工作量。

如果不存在,那就说明这个图片不在图库中;如果存在,我们再通过散列表中存储的文件路径,获取到这个已经存在的图片,跟现在要插入的图片做全量的比对,看是否完全一样。如果一样,就说明已经存在;如果不一样,说明两张图片尽管唯一标识相同,但是并不是相同的图片。

四、应用三:散列函数

散列函数是设计一个散列表的关键。它直接决定了散列冲突的概率和散列表的性能。不过,相对哈希算法的其他应用,散列函数对于散列算法冲突的要求要低很多。即便出现个别散列冲突,只要不是过于严重,我们都可以通过开放寻址法或者链表法解决。

五、应用四:数据校验

比如在从服务器下载大文件时,一般将文件先分片,从多个机器上并行下载,最后再合在一起。下载的文件块有可能是被宿主机器恶意修改过的,又或者下载过程中出现了错误,所以下载的文件块可能不是完整的。就需要校验。可以将原始数据计算哈希值,再将下载来的文件计算哈希值,若相同,则下载文件是源文件。

六、应用五:负载均衡

负载均衡为例,常见的负载均衡方法有很多,但是它们的优缺点也都很明显:

  • 随机访问策略。系统随机访问,缺点:可能造成服务器负载压力不均衡,俗话讲就是撑的撑死,饿的饿死。
  • 轮询策略。请求均匀分配,如果服务器有性能差异,则无法实现性能好的服务器能够多承担一部分。
  • 权重轮询策略。权值需要静态配置,无法自动调节,不适合对长连接和命中率有要求的场景。
  • Hash取模策略。不稳定,如果列表中某台服务器宕机,则会导致路由算法产生变化,由此导致命中率的急剧下降。
  • 一致性哈希策略。

除了一致性哈希策略外,哈希取模使用的较多。

哈希取模:
负载均衡时,假设现有4台服务器(编号分别为0、1、2, 3),使用哈希取模的计算方式则是:对访问者的IP,通过固定算式hash(IP) % N(N为服务器的个数),使得每个IP都可以定位到特定的服务器。

例如现有IP地址 10.58.34.31,对IP哈希取模策时,计算结果为2,即访问编号为2的服务器。

哈希取模的问题:
1.如果服务器宕机,或者新扩充了一台机器,那么这个服务器个数N将会变化,这个哈希算法将会变化,所有的缓存的负载信息都需要重新更新。
2.分库分表时,通常是根据用户的 ID 哈希取模得到的值然后路由到对应的存储位置,计算公式为:hash(userId) % N,其中N为分库或分表的个数。如果新增了一台机器,为了数据可用,需要做数据迁移,按照新的路由规则对所有用户重新分配存储地址。每次的库或表的数量改变你都需要做一次全部用户信息数据的迁移。这个工作量相当费时费力。

  1. 如果客户端很多,映射表可能会很大,比较浪费内存空间;
  2. 客户端下线、上线,服务器扩容、缩容都会导致映射失效,这样维护映射表的成本就会很大;

解决:一致性哈希算法。

一致性哈希:
一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数 H 的值空间为 0 ~ 2^32-1(即哈希值是一个32位无符号整形,这个数值是int的最大取值)。
整个空间圆按顺时针方向布局,圆环的正上方的点代表0,0点右侧的第一个点代表1。以此类推2、3、4、5、6……直到232-1。
在这里插入图片描述

那么,一致性哈希算法与上图中的圆环有什么关系呢?仍然以之前描述的场景为例,假设我们有4台服务器,服务器0、服务器1、服务器2,服务器3,那么,在生产环境中,这4台服务器肯定有自己的 IP 地址或主机名,我们使用它们各自的 IP 地址或主机名作为关键字进行哈希计算,使用哈希后的结果对2^32取模,多个服务器都通过这种方式进行计算,最后都会各自映射到圆环上的某个点,这样每台机器就能确定其在哈希环上的位。把原始数据得到的模值将它负载给该值下一个顺时针最近的服务器。

新增一个服务器,对应地再在环上根据哈希算法添加一个值即可。
删除同理。

但是会出现数据倾斜问题,可以将一个服务器加入其它信息计算多个哈希值,来讲服务器虚拟出更多的结点,从而每个服务器都有很多对应结点。避免了数据都集中分配给某个服务器的情况

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,哈希算法还在数据分片、分布式存储中有应用,可以继续了解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值