前言:

由于MD5加密技术是一项单向的加密技术,不可以进行逆转,所以即使当我们知道加密后的数据也无法还原。安全性较高。


几种MD5的使用方法

方法一:(按照书上实例的方法)

MD5 加密以后生成byte数组,但是由于我们通常在数据库中保存以字符串的形式保存数据,所以我们经常会将转换以后的byte数组转换为字符串

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* @date 2017年10月30日 上午11:13:12
* @author SiVan
*/
package com.md5;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* @author SiVan
* @time 2017年10月30日 上午11:13:12
* @TODO TODO md5加密
*/
public class Test {

public static byte[] encryptMD5(byte[] data) throws NoSuchAlgorithmException {

/*指定加密算法*/
MessageDigest digest = MessageDigest.getInstance("MD5");
/*进行加密*/
digest.update(data);

/*返回加密后的byte数组*/
return digest.digest();
}

/**
*
* @param data
* @return 将加密后的byte 转换为 字符串
* @throws NoSuchAlgorithmException
*/
public static String encryptMD5toString(byte[] data) throws NoSuchAlgorithmException {
String str = "";
String str16;
for ( int i = 0; i < data.length; i++ ){
str16 = Integer.toHexString(0xFF & data[i]);
/*如果长度为1,前位补0*/
if (str16.length() == 1) {
str = str + "0" + str16;
} else {
str = str + str16;
}
}
return str;
}

public static void main(String[] args) throws NoSuchAlgorithmException {
String st = "admin";
System.out.println(encryptMD5toString(encryptMD5(st.getBytes())));
System.out.println(encryptMD5(st.getBytes()));
}
}

方法二:(之前拷贝的一个MD5工具类)

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
30
31
32
33
34
35
36
37
38
39
40
41
package com.md5;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* MD5工具类,需要直接使用即可
* @author SiVan
* @time 2017年10月30日 上午11:37:32
* @TODO TODO
*/
public class MD5Util {

private static String byteHEX(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}

public static String getMD5(String source) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
messageDigest.update(source.getBytes());
byte[] b = messageDigest.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
sb.append(byteHEX(b[i]));
}

/* sb.setCharAt(sb.length()-1, (char)(sb.charAt(sb.length()-1)+1));*/
return sb.toString();
}
}

方法三:(摘自百度百科上面的算法)

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* @date 2017年10月30日 上午11:33:38
* @author SiVan
*/
package com.md5;

/**
* @author SiVan
* @time 2017年10月30日 上午11:33:38
* @TODO TODO
*/
public class MD5{
/*
*四个链接变量
*/
private final int A=0x67452301;
private final int B=0xefcdab89;
private final int C=0x98badcfe;
private final int D=0x10325476;
/*
*ABCD的临时变量
*/
private int Atemp,Btemp,Ctemp,Dtemp;

/*
*常量ti
*公式:floor(abs(sin(i+1))×(2pow32)
*/
private final int K[]={
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
/*
*向左位移数,计算方法未知
*/
private final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
15,21,6,10,15,21,6,10,15,21,6,10,15,21};


/*
*初始化函数
*/
private void init(){
Atemp=A;
Btemp=B;
Ctemp=C;
Dtemp=D;
}
/*
*移动一定位数
*/
private int shift(int a,int s){
return(a<<s)|(a>>>(32-s));
/*右移的时候,高位一定要补零,而不是补充符号位*/
}
/*
*主循环
*/
private void MainLoop(int M[]){
int F,g;
int a=Atemp;
int b=Btemp;
int c=Ctemp;
int d=Dtemp;
for(int i = 0; i < 64; i ++){
if(i<16){
F=(b&c)|((~b)&d);
g=i;
}else if(i<32){
F=(d&b)|((~d)&c);
g=(5*i+1)%16;
}else if(i<48){
F=b^c^d;
g=(3*i+5)%16;
}else{
F=c^(b|(~d));
g=(7*i)%16;
}
int tmp=d;
d=c;
c=b;
b=b+shift(a+F+K[i]+M[g],s[i]);
a=tmp;
}
Atemp=a+Atemp;
Btemp=b+Btemp;
Ctemp=c+Ctemp;
Dtemp=d+Dtemp;

}
/*
*填充函数
*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
*填充方式为先加一个0,其它位补零
*最后加上64位的原来长度
*/
private int[] add(String str){
int num=((str.length()+8)/64)+1;/*以512位,64个字节为一组*/
int strByte[]=new int[num*16];/*64/4=16,所以有16个整数*/
for(int i=0;i<num*16;i++){/*全部初始化0*/
strByte[i]=0;
}
int i;
for(i=0;i<str.length();i++){
strByte[i>>2]|=str.charAt(i)<<((i%4)*8);/*一个整数存储四个字节,小端序*/
}
strByte[i>>2]|=0x80<<((i%4)*8);/*尾部添加1*/
/*
*添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
*/
strByte[num*16-2]=str.length()*8;
return strByte;
}
/*
*调用函数
*/
public String getMD5(String source){
init();
int strByte[]=add(source);
for(int i=0;i<strByte.length/16;i++){
int num[]=new int[16];
for(int j=0;j<16;j++){
num[j]=strByte[i*16+j];
}
MainLoop(num);
}
return changeHex(Atemp)+changeHex(Btemp)+changeHex(Ctemp)+changeHex(Dtemp);

}
/*
*整数变成16进制字符串
*/
private String changeHex(int a){
String str="";
for(int i=0;i<4;i++){
str+=String.format("%2s", Integer.toHexString(((a>>i*8)%(1<<8))&0xff)).replace(' ', '0');

}
return str;
}
/*
*单例
*/
private static MD5 instance;
public static MD5 getInstance(){
if(instance==null){
instance=new MD5();
}
return instance;
}

private MD5(){};

public static void main(String[] args){
String str=MD5.getInstance().getMD5("admin");
System.out.println(str);
}
}