一、概述
java.对于给定数量的更新数据,digest
方法只能被调用一次。digest
方法被调用后,MessageDigest 对象被重新设置成其初始状态。
java.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 更新摘要。 |
public static MessageDigest getInstance(String algorithm)
MessageDigest.getInstance("SHA");
MessageDigest.getInstance("sha");
MessageDigest.getInstance("sHa");
调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:
public static MessageDigest getInstance(String algorithm, String provider);
调用 getInstance 将返回已初始化过的MessageDigest对象。因此,它不需要进一步的初始化。
public void update(byte input);
public void update(byte[] input);
public void update(byte[] input, int offset, int len);
2.3、计算摘要
public byte[] digest();
public byte[] digest(byte[] input);
public int digest(byte[] buf, int offset, int len);
public void update(byte[] input)
,接着调用不带参数的 digest 方法.
三、例子演示
MessageDigest m = MessageDigest.getInstance("MD5");
MessageDigest类也是一个工厂类,其构造器是受保护的,不允许直接使用new MessageDigist( )来创建对象,而必须通过其静态方法getInstance( )生成MessageDigest对象。其中传入的参数指定计算消息摘要所使用的算法,常用的有"MD5","SHA"等。
m.update(x.getBytes("UTF8"));
分析:x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。
byte s[] = m.digest();
分析:执行MessageDigest对象的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();
}
3.2、示例一
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 block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.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();
}
}
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));