MessageDigest
- 可用于为文件生成sha1 md5 等校验信息,对文件进行文件完整性校验
//获取MessageDigest通过getInstance
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
File f = new File("c:\\install.log");
if(!f.isFile()){return;}
FileInputStream Fis= new FileInputStream(f);
//此处借助DigestInputStream
DigestInputStream digestInputStream = new DigestInputStream(Fis,messageDigest);
//为文件生成加密信息的字节数组
byte[] res =digestInputStream.getMessageDigest().digest();
//转换16进制
System.out.println(byteArrayToHex(res));
public 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];
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
int index = 0;
for (byte b : byteArray) {
resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b & 0xf];
}
// 字符数组组合成字符串返回
return new String(resultCharArray);
}
DigestInputStream
这里使用的DigestInputStream 通过一个输入流和MessageDigest 获取实例 并通过getMessageDigest 获取具体的MessageDigest 使用MessageDigest 的 digest()得到加密的字节信息
public DigestInputStream(InputStream stream, MessageDigest digest) {
super(stream);
setMessageDigest(digest);
}
public MessageDigest getMessageDigest() {
return digest;
}
digest方法
public byte[] digest() {
/* Resetting is the responsibility of implementors. */
//调用了抽象类的engineDigest方法
byte[] result = engineDigest();
state = INITIAL;
return result;
}
抽象类的具体实现则是在Security.getImpl(…)方法获得sun.security.provider.SHA
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
try {
...
Object[] objs = Security.getImpl(algorithm, "MessageDigest",(String)null);
if (objs[0] instanceof MessageDigest) {
md = (MessageDigest)objs[0];
} else {
md = new Delegate((MessageDigestSpi)objs[0], algorithm);
}
...
}
engineDigest具体调用为sun.security.provider.SHA 的父类sun.security.provider.DigestBase 中的engineDigest
abstract class DigestBase extends MessageDigestSpi implements Cloneable {
...
protected final byte[] engineDigest() {
byte[] var1 = new byte[this.digestLength];
try {
this.engineDigest(var1, 0, var1.length);
return var1;
} catch (DigestException var3) {
throw (ProviderException)(new ProviderException("Internal error")).initCause(var3);
}
}
...
}