zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

2023-09-27 14:29:23 时间


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位的字符串

 private 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];// 每个字节用 16 进制表示的话,使用两个字符

 // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去

 int index = 0;

 // 从第一个字节开始,对MD5的每一个字节转换成16进制字符的转换

 for (byte b : byteArray) {

 // 取字节中高 4 位的数字转换

 // 为逻辑右移(即无符号右移),将符号位一起右移

 resultCharArray[index++] = hexDigits[b 4 0xf];

 // 取字节中低4位的数字转换 

 resultCharArray[index++] = hexDigits[b 0xf];

 // 字符数组组合成字符串返回

 return new String(resultCharArray);

}
下面是一个测试类,用于测试上面的MD5工具类是否有用

class MD5Test{

 public static void main(String[] args) {

 System.out.println(MD5Utils.stringToMD5("OuyangPeng"));

 long startTime = System.currentTimeMillis();

 System.out.println(MD5Utils.fileToMD5("/home/ouyangpeng/Android/CanplayComp/Code.tar.gz"));//9.6G的文件

 long endTime = System.currentTimeMillis();

 System.out.println("Time:" + (endTime - startTime) / 1000);

}
测试结果如下:

30A81CB758C6918C7E43513839002171

05924A988C096A50B9BD4FA2AD7FA733

Time:86

参考链接:

http://blog.csdn.net/xiao__gui/article/details/8148203 http://baike.baidu.co/link?url=1IssoIidKtoOPvWnNHn4HaKsjYy7s4q85qO7uwrhxWA0mXxoiY3-84mss_wdGWpi



====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

===================================================================================


Scala / Java - 采用 MD5 加盐 实现 id 均匀分组 大量 id 场景下经常需要通过 id 进行 AB Test,最常见的就是使用尾号 hash 进行分组,但是由于 id 生成规则以及其他因素,按照尾号分组往往会造成 id 不匀,从而导致 AB Test 效果受影响,所以下文采用 md5 加盐 Hash 的方式,得到更均匀的分组与 AB Test 效果。......
字节卷动 You will never know how excellent you are unless you impel yourself once.