Hash

Hash

Hash(哈希)

首先要知道数据都存储在内存中,假设有几万条商品价格的数据在内存中,我们想从中找到“苹果”价格,如果你事先不知道商品存储规律,就只能一个个去查找,比如第一个是香蕉、第二个是梨,直到第250个才查到苹果。而如果我们记得每个商品价格存在那个位置就没必要去查找,比如直接去查250号的苹果价格。在计算机中的表现就是知道每条数据对应的内存地址,直接去取相应地址的数据。现在的需求是如何在计算机中实现告诉我一个商品描述,瞬间得到该商品信息存储在哪个地址。于是数学家们设计了一套算法,这套算法能够对数据进行一个简单的摘要,可以简单理解为用不同的整数代表不同的数据,这套算法也就是哈希算法。在存储数据时,我们先对数据的一些描述信息,比如“苹果”,进行哈希运算,得到一个整数,将该整数做些简单处理,转化为一个内存地址,然后将数据存在这个地址对应的存储空间。下次取数据时,仍然对描述信息做哈希运算,得到对应的存储地址,然后到该地址直接取到完整的数据。这样就不用一个个去遍历查找了,即便上亿条数据,也可以瞬间得到想要的数据。 还有几个点补充。这种数据储存的地址依赖哈希运算得到的整数,所以存储是不连续的,编程中提到的字典、map一般就是这种数据结构,而另一种数据结构“数组”则是连续存储的,这两种数据结构各有优缺点各有用途。还有哈希具体的算法实现有很多,也可以根据不同的需求进行不断完善改进。哈希可以对任意数据运算,包括文本,电影,图片,这个很容易理解,因为计算机中数据本质都是二进制01。 还有个很重要的点,哈希运算得到的值并不一定唯一,也就是不同数据有可能哈希值相同。这个也很容易理解,比如我们生成一个8位的哈希值,只要正数,最多也就127个数,如果对1000个数据进行运算,生成1-127之间的数,那必然会有重复。当然这个例子比较极端,我们取的位数不可能那么小。一般重复率极低,我们也有其他办法应对重复的问题。

总引

  1. 定义:哈希是一种单向函数,可以将任意长度的输入(通常称为“消息”)转换为固定长度的输出,这个输出称为“哈希值”或“哈希码”。

  2. 单向性:哈希函数是单向的,意味着从哈希值几乎不可能反推出原始输入。

  3. 确定性:对于给定的输入,哈希函数总是产生相同的哈希值。

    1. info

      所以对于密码的hash操作实际上先把密码进行hash,然后存入数据库,当用户再次登录的时候,会把输入的内容进行hash操作,然后和数据库的内容进行对比看是否一致

  4. 快速计算:哈希函数通常计算速度很快。

  5. 用途:哈希常用于数据完整性验证、密码存储、数据索引等场景。

  6. 但是并不是绝对安全的

    1. 彩虹表:彩虹表是一种预先计算好的哈希值和它们对应的原始输入的数据库。攻击者可以使用彩虹表来查找哈希值对应的原始数据。
    2. 暴力破解:通过尝试所有可能的输入直到找到一个产生相同哈希值的输入。
    3. 字典攻击:使用一个包含常见密码或特定词汇的字典来尝试匹配哈希值。
    4. 哈希碰撞:找到两个不同的输入,它们产生相同的哈希值。
    5. 侧信道攻击:利用系统实现中的漏洞来获取哈希值。

    为了提高安全性,现代的哈希算法(如 SHA-256)设计得非常复杂,以抵抗上述攻击方法。此外,密码存储时通常会采用“盐值”(salt),即一个随机值,与密码结合后再进行哈希,这样可以进一步增强安全性,使得彩虹表攻击变得不可行。

加密

  1. 定义:加密是一种将原始数据(明文)转换为看起来是随机的、无法理解的形式(密文)的过程。这个过程称为加密,而转换后的密文需要通过解密过程还原为原始数据。
  2. 可逆性:与哈希不同,加密是可逆的。使用正确的加密密钥和算法,可以解密密文,恢复原始数据。
  3. 安全性:加密的安全性依赖于加密算法的强度和密钥的保密性。
  4. 用途:加密用于保护数据的机密性,防止未授权的访问和篡改

数组和hash

  1. 数组是利用索引来记录内存地址,通过内存地址直接得到对应的数据或值

  2. hash里的键需要运算后再找到内存地址,如何运算这个键就叫hash函数。比如对键的ASCII码和进行模运算得到的对应的结果

    1. 比如有个hash表只能存5个键值对,比如USA会放到4的地址,所以无论输入是多长,输出会根据hash算法变成固定的长度(此时是模运算)

      1. 但是此时不可避免的会出现余数相等,即不同的输入得到相同的输出,所以会出现hash碰撞
    2. 开放寻址法

      1. 线性探测方法,如果当前位置发生冲突,则直接放到下一个没有被占据的位置,但是会让数据聚集,发生一次聚集现象,解决方法是二次探测方法,就是先找11的位置,如果再次冲突就找22的位置然后33

      2. 开放寻址法是一种解决哈希表冲突的方法,它要求哈希表中的所有槽位都可用于存储数据。当发生冲突时,算法会寻找表中的下一个空闲位置来存储数据。开放寻址法有几种不同的探测技术:

        1. 线性探测(Linear Probing) :从发生冲突的位置开始,线性地探测下一个空闲位置。
        2. 二次探测(Quadratic Probing) :使用二次函数(如 𝑖2i2)来确定探测的步长。
        3. 双重哈希(Double Hashing) :使用第二个哈希函数来确定探测的步长。

        开放寻址法的优点是它不需要额外的存储空间来存储数据,因为所有的数据都存储在哈希表本身中。但是,这种方法可能导致聚集现象,即连续的元素聚集在一起,这可能会降低查找效率。

    3. 封闭寻址法

      1. 链表法,就是对应的位置实际上变成链表进行存储,一个位置可以存一个链的数据,但是当想找的数据都是基于这个位置的时候,查询会很麻烦很慢,也可能发生集群现象,数据会集中出现在某几个节点里

      2. 封闭寻址法,也称为链地址法(Chaining),是一种通过链表来解决哈希表冲突的方法。在这种方法中,哈希表的每个槽位都包含一个指向链表的指针,所有映射到该槽位的元素都存储在这个链表中。

        当发生冲突时,新元素不是替换掉原有元素,而是被添加到该槽位的链表中。这种方法的一个关键优势是它可以处理大量冲突,因为所有的冲突元素都可以存储在同一个槽位的链表中。

        封闭寻址法的优点是可以很好地处理冲突,并且可以通过优化链表(如使用平衡树代替链表)来提高性能。但是,这种方法需要额外的存储空间来维护链表,并且当链表变得非常长时,查找效率可能会降低。

  3. 优秀的hash算法不会生成相对固定的值,而是直接固定死的值,叫摘要,比如128bits长度的,256bits长度的,512bits的等

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值