大家好,又见面了,我是你们的朋友全栈君。
转自:http://blog.csdn.net/hudashi/article/details/8394158
参考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html
MessageDigest
类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成
散列码。
信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。关于
信息摘要
和
散列码
请参照《
数字证书简介
》
MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用 update
方法处理数据。任何时候都可以调用 reset
方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest
方法之一完成哈希计算并返回结果。
对于给定数量的更新数据,digest
方法只能被调用一次。digest
方法被调用后,MessageDigest 对象被重新设置成其初始状态。
MessageDigest 的实现可随意选择是否实现 Cloneable 接口。客户端应用程可以通过尝试复制和捕获 CloneNotSupportedException 测试可复制性:
MessageDigest md = MessageDigest.getInstance("SHA");
try {
md.update(toChapter1);
MessageDigest tc1 = md.clone();
byte[] toChapter1Digest = tc1.digest();
md.update(toChapter2);
...etc.
} catch (CloneNotSupportedException cnse) {
throw new DigestException("couldn't make digest of partial content");
}
注意1:即时给定MessageDigest的实现是不可复制的,则仍然能够通过getInstance方法实例化几个实例计算来同时进行摘要信息的计算。
注意2:由于历史原因,此类是抽象的,是从 MessageDigestSpi
扩展的。应用程序开发人员只应该注意在此 MessageDigest
类中定义的方法;超类中的所有方法是供希望提供自己的信息摘要算法实现的加密服务提供者使用的。
注意3:MessageDigest并不是单实例的。如下代码所示:
try
{
MessageDigest mdTemp1 = MessageDigest.getInstance("MD5");
MessageDigest mdTemp2= MessageDigest.getInstance("MD5");
MessageDigest mdTemp3= MessageDigest.getInstance("MD5");
System.out.println("mdTemp1==mdTemp2?:"+(mdTemp1==mdTemp2));
System.out.println("mdTemp2==mdTemp3?:"+(mdTemp2==mdTemp3));
} catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
运行结果
mdTemp1==mdTemp2?:false
mdTemp2==mdTemp3?:false
构造方法摘要 | |
---|---|
protected |
MessageDigest(String algorithm) 创建具有指定算法名称的MessageDigest 实例对象。 |
方法摘要 | |
---|---|
Object |
clone() 如果实现是可复制的,则返回一个副本。 |
byte[] |
digest() 通过执行诸如填充之类的最终操作完成哈希计算。 |
byte[] |
digest(byte[] input) 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算。 |
int |
digest(byte[] buf, int offset, int len) 通过执行诸如填充之类的最终操作完成哈希计算。 |
String |
getAlgorithm() 返回标识算法的独立于实现细节的字符串。 |
int |
getDigestLength() 返回以字节为单位的摘要长度,如果提供程序不支持此操作并且实现是不可复制的,则返回 0。 |
static MessageDigest |
getInstance(String algorithm) 生成实现指定摘要算法的 MessageDigest 对象。 |
static MessageDigest |
getInstance(String algorithm, Provider provider) 生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。 |
static MessageDigest |
getInstance(String algorithm, String provider) 生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。 |
Provider |
getProvider() 返回此信息摘要对象的提供程序。 |
static boolean |
isEqual(byte[] digesta, byte[] digestb) 比较两个摘要的相等性。 |
void |
reset() 重置摘要以供再次使用。 |
String |
toString() 返回此信息摘要对象的字符串表示形式。 |
void |
update(byte input) 使用指定的字节更新摘要。 |
void |
update(byte[] input) 使用指定的字节数组更新摘要。 |
void |
update(byte[] input, int offset, int len) 使用指定的字节数组,从指定的偏移量开始更新摘要。 |
void |
update(ByteBuffer input) 使用指定的 ByteBuffer 更新摘要。 |
MessageDigest
对象
散列码
)要做的第一步是创建
MessageDigest
对象
实例。像所有的引擎类一样,获取某类报文摘要算法(即
散列算法
,比如
MD5
)的
MessageDigest
对象的途径是调用
MessageDigest
类中的
getInstance
静态
factory
方法:
public static MessageDigest getInstance(String algorithm)
MessageDigest . getInstance ( "SHA" );MessageDigest . getInstance ( "sha" );MessageDigest . getInstance ( "sHa" );
public static MessageDigest getInstance(String algorithm, String provider);
MessageDigest对象。因此,它不需要进一步的初始化。
MessageDigest
传送要计算的数据
MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个
update(更新)方法来完成:
public void update ( byte input );public void update ( byte [] input );public void update ( byte [] input , int offset , int len );
MessageDigest对象
提传送要计算的数据后,你就可以调用以下某个 digest(摘要)方法来计算摘要(即
生成
散列码):
public byte [] digest ();public byte [] digest ( byte [] input );public int digest ( byte [] buf , int offset , int len );
public void update(byte[] input)
三、例子演示
MessageDigest类提供了计算消息摘要
(
即生成
散列码
)的方法,首先生成对象,执行其
update( )方法可
digest( )方法即可得到消息摘要。具体步骤如下:
MessageDigest m=MessageDigest.getInstance("MD5");
getInstance( )生成
MessageDigest对象。
MD5“,”
SHA“等。
m.update(x.getBytes("UTF8" ));
byte s[ ]=m.digest( );
static String convertToHexString ( byte data []) {StringBuffer strBuffer = new StringBuffer ();for ( int i = 0 ; i < data . length ; i ++) {strBuffer . append ( Integer . toHexString ( 0xff & data [ i ]));}return strBuffer . toString ();}
public class MessageDigestDemo extends Thread {public void run () {String text = "abc" ;byte data [] = null ;MessageDigest m ;try {data = text . getBytes ( "UTF8" );m = MessageDigest . getInstance ( "MD5" );m . update ( data );byte resultData [] = m . digest ();System . out . println ( convertToHexString ( resultData ));} catch ( NoSuchAlgorithmException e ) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}static String convertToHexString ( byte data []) {StringBuffer strBuffer = new StringBuffer ();for ( int i = 0 ; i < data . length ; i ++) {strBuffer . append ( Integer . toHexString ( 0xff & data [ i ]));}return strBuffer . toString ();}}
900150983cd24fb0d6963f7d28e17f72
sun.misc.BASE64Encoder进行简单的加密。
public String md5sumWithEncoder ( String text ) throws NoSuchAlgorithmException ,UnsupportedEncodingException {/*确定计算方法*/MessageDigest md5 = MessageDigest . getInstance ( "MD5" );BASE64Encoder base64en = new BASE64Encoder ();/*加密后的散列码字符串*/String strMd5 = base64en . encode ( md5 . digest ( text . getBytes ( "utf-8" )));return strMd5 ;}
String str = "0123456789"System . out . println ( md5sumWithEncoder ( str ));
3.4、示例三
一点关于计算MD5的封装
》
转自:http://www.2cto.com/kf/201312/263037.html一个有详细注释的例子
在 Java 中,java.security.MessageDigest 中已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数。然后将此 128 位(即16 个字节)转换成 16 进制表示即可。
Java已经实现了MD5、SHA1算法。利用java.security.MessageDigest类就可以获取字符串和文件的MD5以及SHA1结果下面是一个工具类,可以获取字符串和文件进行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
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
|
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
/**
* MD5工具类,获取字符串或者文件的MD5值
* @author ouyangpeng
*/
public class MD5Utils {
/**
* 通过MD5加密字符串
* @param HASH_ALGORITHM
* 加密算法,可以是MD5,SHA1
* @param input
* 字符串
* @return 已经通过MD5算法加密的32位字符串
*/
public final static String stringToMD5(String input) {
try {
// 拿到一个MD5转换器,如果想要SHA1参数换成”SHA1”)
MessageDigest messageDigest = MessageDigest.getInstance(MD5);
// 输入的字符串转换成字节数组
byte [] inputByteArray = input.getBytes();
// inputByteArray是输入字符串转换得到的字节数组
messageDigest.update(inputByteArray);
// 转换并返回结果,也是字节数组,包含16个元素
byte [] resultByteArray = messageDigest.digest(); // MD5 的计算结果是一个 128 位的长度整数,
// 字符数组转换成字符串返回
return byteArrayToHex(resultByteArray);
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 通过MD5加密文件
* @param inputFile 文件路径
* @return 已经通过MD5算法加密的32位字符串
*/
public final static String fileToMD5(String inputFile) {
int bufferSize = 256 * 1024 ; // 定义缓冲区大小
FileInputStream fileInputStream = null ;
DigestInputStream digestInputStream = null ;
try {
MessageDigest messageDigest = MessageDigest.getInstance(MD5);
fileInputStream = new FileInputStream(inputFile);
digestInputStream = new DigestInputStream(fileInputStream, messageDigest);
byte [] buffer = new byte [bufferSize];
while (digestInputStream.read(buffer) > 0 )
;
messageDigest = digestInputStream.getMessageDigest();
byte [] resultByteArray = messageDigest.digest();
return byteArrayToHex(resultByteArray);
} catch (Exception e) {
} finally {
try {
digestInputStream.close();
} catch (Exception e2) {
}
}
return null ;
}
/**
* @param byteArray
* byte数组
* @return 转后后的32位的字符串
*/
private static String byteArrayToHex( byte [] byteArray) {
// 首先初始化一个字符数组,用来存放每个16进制字符
char [] hexDigits = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' };
// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
char [] resultCharArray = new char [byteArray.length * 2 ]; // 每个字节用 16 进制表示的话,使用两个字符
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
int index = 0 ;
// 从第一个字节开始,对MD5的每一个字节转换成16进制字符的转换
for ( byte b : byteArray) {
// 取字节中高 4 位的数字转换
//>>> 为逻辑右移(即无符号右移),将符号位一起右移
resultCharArray[index++] = hexDigits[b >>> 4 & 0xf ];
// 取字节中低4位的数字转换
resultCharArray[index++] = hexDigits[b & 0xf ];
}
// 字符数组组合成字符串返回
return new String(resultCharArray);
}
}
|
下面是一个测试类,用于测试上面的MD5工具类是否有用
1
2
3
4
5
6
7
8
9
|
class MD5Test{
public static void main(String[] args) {
System.out.println(MD5Utils.stringToMD5(OuyangPeng));
long startTime = System.currentTimeMillis();
System.out.println(MD5Utils.fileToMD5(/home/ouyangpeng/Android/CanplayComp/Code.tar.gz)); //9.6G的文件
long endTime = System.currentTimeMillis();
System.out.println(Time: + (endTime - startTime) / 1000 );
}
}
|
测试结果如下:
1
2
3
|
30A81CB758C6918C7E43513839002171
05924A988C096A50B9BD4FA2AD7FA733
Time: 86
|
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/160593.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...