我的Java开发学习之旅------>工具类:Java获取字符串和文件进行MD5值(一)

2014-11-24 08:07:41 · 作者: · 浏览: 2

ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示“上传成功”!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象。百度了一下才发现所谓的“秒传”是常见的“忽略式”上传方式,就是您上传了一个文件名为111.exe,MD5为一个数,有一个网友以前也上传一个叫222.exe,MD5和您上传的文件MD5码一模一样,所以这个文件上传到服务器上的时间就很短了,这是因为别人上传过这个文件,您上传这个文件,服务器上有这个文件了,所以只需要把这个文件复制一份到您的网盘上就可以了。

秒传的原理详细解释  

上传到网盘的每个文件,服务器都会校验MD5码。如果这个您上传的文件MD5码与已经存在于服务器里的文件的MD5码相同的话,网盘服务器将会判断成为重复文件,只需要复制副本保存在网盘上即可,无需重新保存,因为有过目前这个文件,于是很快完成上传任务,并在有人需要下载的时候将原有的该文件的下载地址放出。这样实现了服务器的高效运作。

怎样不秒传?  

把你要上传的东西压缩成RAR,东西上传,服务器会先做MD5校验,如果服务器上有一样的东西,它就直接给你个新地址,其实你下载的都是服务器上的同一个文件,想要不秒传,其实只要让MD5改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5就变了,就不会秒传了。  但是有些文件我们不好改变,也不想改变,那其实只要压缩一下,MD5就变了,而下载的人也能获得最原始的资料,不过就是加压要花费一点时间。

下面来学习学习MD5的相关知识,MD5 即Message-Digest Algorithm 5(信息-摘要算法5 ),是一种用于产生数字签名的单项散列算 法,在1991年由MIT Laboratory for Computer Science(MIT计算机科学实验室)和RSA Data Security Inc(RSA数据安全公司)的Ronald L. Rivest教授开发出来,经由MD2、MD3和MD4发展而来。MD5算法的使用不需要支付任何版权费用。它的作用是让大容量信息在用数字签名软件签私人密匙前被压缩成一种保密的格式(将一个任意长度的“字节串”通过一个不可逆的字符串变换算法变换成一个128bit的大整数 ,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。)
在 Java 中,java.security.MessageDigest 中已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数。然后将此 128 位(即16 个字节)转换成 16 进制表示即可。

Java已经实现了MD5、SHA1算法。利用java.security.MessageDigest类就可以获取字符串和文件的MD5以及SHA1结果下面是一个工具类,可以获取字符串和文件进行MD5值。

import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
/**
 * MD5工具类,获取字符串或者文件的MD5值
 * @author ouyangpeng
 * @link http://blog.csdn.net/ouyang_peng
 */
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位的字符串