梦想还是要有的,万一忘了咋办?

0%

哈希算法

目录

  • 什么是哈希算法
  • 哈希算法的特点
  • 相关名词介绍
  • 常见哈希算法
  • 哈希算法应用场景
  • Java示例代码

介绍

定义

将任意长度二进制值串映射为固定长度的二进制串,这个映射规则就是哈希算法,而通过原始数据映射之后得到的二进制串就是哈希值

特点

  • 不可逆
  • 唯一性,相同内容得到哈希值一定相同,不同内容得到哈希值不同,但理论上是不能确保唯一性。
  • 高灵敏性,对输入数据敏感,哪怕只有1bit不同最后哈希值也大不相同
  • 高效,针对较长文本也可以高效计算出哈希值

哈希碰撞

不同的值最终得到相同的哈希值。鸽巢原理可以解释为何一定会存在哈希碰撞。

鸽巢原理

鸽巢原理(也叫抽屉原理),它是说,如果有 10 个鸽巢,有 11 只鸽子,那肯定有 1 个鸽巢中的鸽子数量多于 1 个,换句话说就是,肯定有 2 只鸽子在 1 个鸽巢内。

彩虹表

一个预先计算好的常用口令和它们的哈希算法(MD5)的对照表,黑客会用这个表来反查原始密码。

加盐

加盐的目的在于使黑客的彩虹表失效,即使用户使用常用口令,也无法从MD5反推原始口令。

常见哈希算法

|算法|长度(位)|长度(字节)|
|–|–|–|–|
|MD5(Message-Digest Algorithm)|128bits|16bytes|
|SHA-1(Secure Hash Algorithm)|160bits| 20bytes|
|RipeMD-160| 160bits| 20bytes|
|SHA-256| 256bits| 32bytes|
|SHA-512| 512bits| 64bytes|

应用场景

  • 网站密码加密存储(不可逆、唯一性)
  • 文件校验(唯一性)
  • 数字签名(唯一性)
  • 负载均衡、数据分片、分布式存储(唯一性)

示例

Md5

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) throws Exception {
// 创建一个MessageDigest实例:
MessageDigest md = MessageDigest.getInstance("MD5");
// 反复调用update输入数据:
md.update("Hello".getBytes("UTF-8"));
md.update("World".getBytes("UTF-8"));
byte[] result = md.digest(); // 16 bytes: 68e109f0f40ca72a15e05cc22786f8e6
System.out.println(new BigInteger(1, result).toString(16));
}
}

SHA

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) throws Exception {
// 创建一个MessageDigest实例:
MessageDigest md = MessageDigest.getInstance("SHA-1");
// 反复调用update输入数据:
md.update("Hello".getBytes("UTF-8"));
md.update("World".getBytes("UTF-8"));
byte[] result = md.digest(); // 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2
System.out.println(new BigInteger(1, result).toString(16));
}
}