6.7 实例:文件校验

秉承程序员的执著,发现问题就要解决问题!既然我们已经看到了MySQL下载页面上的MD5信息,就要对其文件做MD5校验!通过下载页面下载MySQL Essential 5.1.38的Windows安装版(mysql-essential-5.1.38-win32.msi),并将其放置在D盘根目录下。接下来,我们要对这个文件做一次MD5校验。如果校验结果与下载页面上给出的MD5信息不一致,则说明文件在下载的过程中被篡改了!

这个校验并不复杂,我们分别通过testByMessageDigest()和testByDigestUtils()方法做校验处理,如代码清单6-22所示。

代码清单6-22 校验下载文件一致性


import static org.junit.Assert.*;

import java.io.File;

import java.io.FileInputStream;

import java.security.DigestInputStream;

import java.security.MessageDigest;

import org.apache.commons.codec.binary.Hex;

import org.apache.commons.codec.digest.DigestUtils;

import org.junit.Test;

/**

*消息摘要编码测试<br>

*用于校验文件的MD5值

*<pre>

*文件为mysql-essential-5.1.38-win32.msi

*存放于D盘根目录

*MD5值为5a077abefee447cbb271e2aa7f6d5a47

*</pre>

*@author梁栋

*@version 1.0

*@since 1.0

*/

public class MD5Test{

/**

*验证文件的MD5值

*@throws Exception

*/

@Test

public void testByMessageDigest()throws Exception{

//文件路径

String path="D:\mysql-essential-5.1.38-win32.msi";

//构建文件输入流

FileInputStream fis=new FileInputStream(new File(path));

//初始化MessageDigest,并指定MD5算法

DigestInputStream dis=new DigestInputStream(fis, MessageDigest.getInstance("MD5"));

//流缓冲大小

int buf=1024;

//缓冲字节数组

byte[]buffer=new byte[buf];

//当读到值大于-1就继续读

int read=dis.read(buffer,0,buf);

while(read>-1){

read=dis.read(buffer,0,buf);

}

//关闭流

dis.close();

//获得MessageDigest

MessageDigest md=dis.getMessageDigest();

//摘要处理

byte[]b=md.digest();

//十六进制转换

String md5hex=Hex.encodeHexString(b);

//验证

assertEquals(md5hex,"5a077abefee447cbb271e2aa7f6d5a47");

}

/**

*验证文件的MD5值

*@throws Exception

*/

@Test

public void testByDigestUtils()throws Exception{

//文件路径

String path="D:\mysql-essential-5.1.38-win32.msi";

//构建文件输入流

FileInputStream fis=new FileInputStream(new File(path));

//使用DigestUtils做MD5Hex处理

String md5hex=DigestUtils.md5Hex(fis);

//关闭流

fis.close();

//验证

assertEquals(md5hex,"5a077abefee447cbb271e2aa7f6d5a47");

}

}


既然两种方法都是MD5文件校验,那么会有什么差异呢?

从测试结果来说,一定都是通过,那么在效率上呢?如图6-10所示。

figure_0224_0050

图 6-10 MD5文件校验处理测试结果

作者做了反复测试,其测试结果与上图基本相符,两种方法实现效率较为接近。

如果只是对文件做MD5校验,用Commons Codec来实现再合适不过了。对文件做MD5处理/校验,已经是一件很平常的事情了。相信上述简要的代码实现,对读者朋友一定会很有益处。