数据结构与算法之美(九)哈希算法

介绍

哈希算法:将任意长度的二进制值串映射为**固定长度的二进制值串(哈希值)**的映射规则

要求:

  • 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);
  • 对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同;
  • 散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小;
  • 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。

哈希算法的应用

安全加密:难以反向推导

常用于加密的哈希算法:

  • MD5:哈希值是128bit,表示为16进制编码就是32个字符,可以有 2 128 2^{128} 2128个哈希值,散列冲突的概率小于 1 / 2 128 1/2^{128} 1/2128
  • SHA
  • DES
  • AES

针对字典攻击(用户信息被脱库后,黑客拿到用户密码的密文,但可以通过猜的方式来破解密码),可以引入盐(salt)跟用户的密码组合在一起之后,再做哈希加密。

唯一标识:图片重复比对

  • 对大数据作信息摘要,通过一个较短的二进制编码来表示很大的数据
  • 区块链:区块链是一块块区块组成的,每个区块分为区块头和区块体。区块头上保存着自己的区块体的哈希值和上一个区块头的哈希值。因为这种链式关系和哈希值的唯一性,只要区块链上任意一个区块被修改过,后面所有区块的哈希值就不对了。区块链使用的是SHA256哈希算法,计算哈希值非常耗时,如果要篡改一个区块,就必须重新计算该区块后面所有的区块的哈希值,短时间内几乎不可能做到。
  • Git commit id

数据校验:下载文件后校验

校验数据的完整性和正确性,例如CRC校验。

散列函数:散列表设计

关注散列值是否能均匀分布、散列函数计算效率

负载均衡

如何能实现一个会话粘滞的负载均衡算法?意思是,在同一个客户端上,在一次会话中的所有请求,都路由到同一个服务器上。

方法一:维护会话id到服务器id的映射,问题是内存会很大、维护成本高;
方法二:会话id作哈希,哈希值对服务器个数取模,就是服务器id

数据分片

例子1: 统计“搜索关键词”出现的次数

  • 问题:有1T日志文件,里面记录了用户的搜索关键词,想要快速统计处每个关键词的搜索次数。
  • 难点:搜索日志过大不能放到一台机器的内存中;如果只用一台机器处理,时间会很长
  • 方案:MapReduce。相同的关键词分配到同一台机器上(搜索关键词->哈希值->对机器数取模->机器id);每个机器分别计算关键词出现的次数,合并起来就是结果

例子2: 图片数量很多时如何快速判断图片是否在图库中

  • 问题:图库中有1亿张图片,如何快速判断给定图片是否在图库中?
  • 难点:图库图片数量太多以致哈希后散列表无法存储在单台机器上
  • 方案:多机处理,让每台机器只维护某一部分图片对应的散列表。每次从图库中读取一个图片,计算唯一标识,然后对机器数取模,得到构建散列表的机器编号;判断时,将图片通过同样的哈希算法得到哈希值后对机器数取模,取相应编号的机器上取查散列表。

分布式存储

海量数据的读写需要分布式缓存,如果单纯通过数据哈希后对机器数取模来决定分配的机器,那在扩容缩容时会导致原缓存的哈希失效,从而穿透缓存直接请求数据库引发雪崩效应。

使用一致性哈希算法可以解决上述问题,基本思想是将哈希值的数据范围化成多个小区间,每台机器负责几个小区间。当有新的机器加入时,就将某几个小区间的数据搬移到新的机器中,这样既不用重新哈希、也保持了各机器上数据数量的均衡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值