9. 摘要流
摘要流在对一组信息进行输入输出操作的同时,将摘要信息记录下来,最后通过getMessageDigest().digest()方法得到摘要信息的byte数组。
摘要流示例代码:对字符串进行摘要和对文件进行摘要。
import java.io.*;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class DigestStreamExam {
public static void main(String[] args) {
String str = "Today is a good day. 今天是个好天气。";
digestString(str);
File file = new File("d:\\a.txt");
digestFile(file);
}
private static void digestFile(File file) {
try {
MessageDigest sha = MessageDigest.getInstance("SHA");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DigestOutputStream digestOutputStream = new DigestOutputStream(byteArrayOutputStream, sha);
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
digestOutputStream.write(buf, 0, len);
}
digestOutputStream.flush();
digestOutputStream.close();
byte[] result = digestOutputStream.getMessageDigest().digest();
for (int i = 0; i < result.length; i++) {
System.out.print(byteToHexString(result[i]));
}
System.out.println();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void digestString(String str) {
try {
MessageDigest sha = MessageDigest.getInstance("SHA");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DigestOutputStream digestOutputStream = new DigestOutputStream(byteArrayOutputStream, sha);
byte[] bytes = str.getBytes();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
byte[] buf = new byte[1024];
int len = 0;
while ((len = byteArrayInputStream.read(buf)) != -1) {
digestOutputStream.write(buf, 0, len);
}
digestOutputStream.flush();
digestOutputStream.close();
byte[] result = digestOutputStream.getMessageDigest().digest();
for (int i = 0; i < result.length; i++) {
System.out.print(byteToHexString(result[i]));
}
System.out.println();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String byteToHexString(byte b) {
String s = Integer.toHexString(b);
int len = s.length();
if (len >= 2) {
s = s.substring(len - 2);
} else {
s = "0" + s;
}
return s;
}
}
运行输出为:
cb3492a453633b7ade978a7214c064b82a332a94
788dc68d752ffb1a12c52c5436cbd4351ba8bf3c
注意,为了输出美观,我提供了一个byteToHexString方法,该方法可以将byte转换为一个两个字符的String,该String中包含了该byte的十六进制格式。
摘要流被广泛用于各种信息的验证中,是一种很常用的手段。