Hash算法

一、定义

Hash译为把…弄糟(乱)。哈希函数又被称为散列函数、杂凑函数。是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间。不同的输入可能会散列成相同的输出,也就是哈希碰撞。

1
2
3
4
5
6
简单说就是:
1.Hash是只能加密,不能解密的算法。如果需要解密只能使用枚举法,不断地试输入的参数
2.输入一个数,哈希函数可以把它变为长度相等的整数(通常为16进制)
3.不同参数->不同的整数
4.同样的参数->同样的整数
5.不同的参数算出的整数有概率相等,称为哈希碰撞

二、哈希函数的实现

这里以一种简单的实现方法:平方取中法

  1. 传入一个字符参数,把该字符参数转换为Unicode序号
  2. 把这个序号平方
  3. 再取平方中的2~7这四位数,得到值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.math.BigDecimal;

public class TestHash {
public static void main(String[] args) {
String a = "abc";
//Unicode加上一位6位数,然后进行平方
double b=Math.pow(Double.parseDouble(StringUnicode(a))+123456,2);
//把科学计数法转换为普通计数法
BigDecimal bd = new BigDecimal(b);
String c = bd.toPlainString();
//截取最后的字符串2~7的数字
System.out.println(c.substring(2,6));
}
/**
* 把String转换为Unicode
* @param string
* @return unicode of string
*/
public static String StringUnicode(String string) {
StringBuffer unicode = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
// 取出每一个字符
char c = string.charAt(i);
// 转换为unicode
unicode.append(Integer.toHexString(c));
}
return unicode.toString();
}
}

这里终端得到的值为

1
2
3
4
5
"C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" ...
7184

Process finished with exit code 0

即更换不同的字符串a,可以输出一个毫无规律的4位数字。而且通过这个四位数无法逆向推到出字符串a。这就是一个简单的哈希算法。

三、常用的几个Hash函数

通过增加Hash函数的输出长度,可以减少Hash碰撞的概率。常用的Hash函数有MD4,MD5,SHA-0,SHA-1,SHA-1。现在大部分加密采用的都是SHA-2,其中比特币的数字签名加密算法的就是SHA-256。

常用的几个Hash函数

四、Hash函数的应用

现在Hash函数基本上是无处不在如平时用到的用户密码、密钥等加密。甚至这几年非常火爆的区块链BTC比特币也是运用SHA-256算法来进行加密防止它人恶意篡改数字签名。

BTC中Hash函数的应用