What is Hash?

Hash 既可以指数据结构中的哈希表(hash table),也可以指常见的加密散列算法(hash algorithm)

Hash表,Hash算法,虽然都叫Hash, 但是 哈希表和哈希算法是不同的概念,它们只是都利用了散列函数的思想而已。

下面来分享两者的区别,哈希表和哈希算法有以下几个主要的不同点:
哈希表和哈希算法是什么:

  • 哈希表是一种数据结构,用于存储和快速查找键值对。
  • 哈希算法则是一种密码学算法,用于将任意长度的输入转换为固定长度的输出。

目的不同:

  • 哈希表的目的是实现高效的数据存储和查找。
  • 哈希算法的目的是提供信息摘要、数字签名等加密安全功能。

可逆性:

  • 哈希表的值是可逆的,可以通过键找到对应的值;
  • 哈希算法的输出是不可逆的,无法从散列值推导出原始输入。

在实际应用中,它们各有优势:
哈希表优势:

  • 提供O(1)时间复杂度的查找、插入、删除操作,效率高。
  • 应用广泛,如缓存、索引、数据去重等。

哈希算法优势:

  • 抗碰撞性强,安全性高,广泛应用于加密、数字签名等安全领域。
  • 可压缩任意长度的数据到固定长度,便于存储和传输。
  • 单向性强,不可逆,适合信息摘要等安全应用。

哈希算法的两个特性:

  1. 不可逆性:无法对一个散列值做逆向操作来获取其原始数据;
  2. 唯一性:不同的数据其计算得出的散列值永远不同,而同一输入计算出的散列值永远一样。

散列函数

散列算法是一种数据结构和算法,它将任意长度的输入数据转换成固定长度的输出数据,称为散列值或者摘要。散列算法的工作原理通常包括以下几个步骤:

  1. 预处理输入数据:

    • 在某些情况下,需要先对输入数据进行填充或格式化,使其满足算法的要求,例如 MD5 算法要求数据长度是 448 位的整数倍。
  2. 初始化状态值:

    • 大多数散列算法会使用一组固定的初始值作为状态寄存器的初始值,这些值通常是常数或者前一次计算的结果。
  3. 迭代压缩函数:

    • 散列算法会反复对输入数据进行处理和压缩。每个压缩步骤都会使用不同的常数、逻辑运算或者数学运算,将当前状态值和当前数据块进行变换,得到新的状态值。
  4. 输出散列值:

    • 经过多轮的压缩计算后,最终会得到一个固定长度的散列值,这就是算法的输出结果。

不同的散列算法在具体实现上会有所不同,比如 MD5 使用 4 个 32 位寄存器,SHA-256 使用 8 个 32 位寄存器。但基本工作原理是相同的:通过预处理、迭代压缩、输出结果等步骤,将任意长度的输入转换成固定长度的输出。

它是怎么防止别逆向回去的?
假设我们使用 SHA-256 散列算法,输入字符串 "hello world" 怎么转换为散列值?
中间不可逆的原理是什么?
todo

Hash表的操作都是O(1) ?

一个简单的原理展示:

  1. 计算机只需调用哈希函数(输入键值);
    准备好哈希映射表,以下面这个字母和数字的简单映射为例:
    A = 1
    B = 2
    C = 3
    D = 4
    E = 5
    ...以此类推。

  2. 计算键的哈希值;
    计算机会对键使用哈希函数。假设使用“乘法”函数,结果如下:
    BAD = 2 × 1 × 4 = 8

  3. 跳转到对应索引并读取值即可;

  4. code example:

    Map<String, String> map = new HashMap<>();
    map.put("BAD", "evil");
    
    String value = map.get("BAD");
    System.out.println(value);
    

    out:

    evil
    

什么是散列函数思想?

  • 将任意长度的输入映射到固定长度的输出(称为散列值或哈希值);
  • 散列函数应该尽可能均匀地分布输入到整个输出范围,即具有良好的分散性(dispersion)。这样可以减少冲突的概率;
  • 散列函数应该是高效的,即计算速度快,便于实现;
  • 散列函数应该尽可能满足单向性和抗碰撞性。单向性指无法从散列值推导出原始输入,抗碰撞性指很难找到两个不同的输入产生相同的散列值。
posted on 2024-01-08 15:44  Mysticbinary  阅读(10)  评论(0编辑  收藏  举报