什么是 MD5 ?

MD5(Message Digest Algorithm,信息摘要算法),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。它后面这个数字 5 是因为它是为了取代 MD4 而发明的。简单的理解,它的作用就是给文件一个唯一标识。 如果我们修改了一个文件的扩展名,文件可能会打不开,但是对于 MD5 来说,并没有什么改变。所以对于一个文件,进行任何的重新命名对于md5校验都是没有用的。



MD5 的应用

这里只提几点我见过的比较频繁的应用情况。

下载文件校验

因为网络并不是完美的,下载大文件的过程中可能会出错(小文件也会,但是通常越大的文件几率越大),这是很正常的现象,网络出现波动是很正常的。所以,通常有些软件的jar或开发工具会额外提供一个文件的md5值下载(因为它很小,通常认为是不会出错的),用于用户校验文件是否下载错误。但是现在网络也是越来越好了,基本上不会错误。(所以我没有使用过,如果用户的网络环境不是很好,下载完毕一定要校验一下,免得出错。)


上传文件

相比之下,md5值上传文件的应用范围就更大了。这里主要的用途是为了文件去重和文件过滤

文件去重

我们知道用户上传的文件中,一般都是有很多重复的,如最近流行的电影、电视剧、游戏或者其它的流行资源。其实它们占据了用户上传文件的很大一部分,所以对于同一份资源,只需要存储一份就可以了。试想一下,一万个用户(一万可能都少了)上传了同一份 4GB 的电影,那么总共需要磁盘容量:4*10000 GB。如果只是上传一份,对于其它用户的上传只是在本地计算文件的 md5值 ,如果相同就认为是同一个文件,那么就只需要 4GB 空间就足够了(当然,这里忽略了记录信息的空间大小,但是相比于文件本身的大小,这些信息还是很小的)。大家可以想一下,这样对于空间的节约是多么巨大的。
大家生活中,应该经常用到,上传一个几个 GB 的大文件,居然几秒钟就完成了,但是稍微有点网络知识的都知道,网络的上传速率是小于下载速率的(这只是对于终端用户来说),下载都达不到的速度,上传更是不可能的。所以,它应该只是进行了一个文件md5值的计算过程,根据计算的结果,如果有就不上传,只是记录一下用户拥有这个文件而已。如果没有的话,就老老实实上传,当然了,这个过程通常很慢。

文件过滤

有一些文件涉及到版权和政策的关系,是不允许用户上传的。所以,对于用户上传文件也会进行校验,然后和后台的黑名单匹配(应该是这样的),如果匹配成功的话,那么文件是无法上传或者上传的文件已经被处理掉了。这样方法的效率很高的,通常用户所谓的乱改名操作是完全没有用的。所以,用户一定要遵守政策和相关平台的规定。



修改文件的 MD5 值

一般情况下,只要改变了文件的二进制内容,文件的md5值一定会改变的。通常有利用压缩文件的方式,将多个文件压缩上传的方式,这样压缩文件的 md5值也会改变,但是有的平台也是可以解压文件的,所以这样也不是万能的。但是通过程序修改和还原文件的二进制数据还是比较容易地,使用Java的流几乎可以对与文件进行任何操作(例如对于文件的每个字节进行加密,这样想还原这个文件就是很难的,或者只是加密一段或者首先创建一个文件,先向文件写入一段固定的数字,再写入相关文件的数据,这样也是很不错的方法。)。对于文件来说,我们可以简单地把它看出是一连串连续地二进制流(逻辑上),将它合并(增加)或者截断(减少)是很简单地操作,这里就是简单的涉及文件 和 IO流的知识了。

我上次写了一个关于文件合并操作的程序,可以将文本、图片和视频进行合并,如果感兴趣,可以参考一下:文件合并(图片+视频),修改md5值,隐藏文件



一个简单的计算 md5 的程序

这个程序是Java网络编程上面的,这里去掉了线程,简化了一下操作,反正只是用于计算md5值,不需要用户的其它操作。

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import javax.xml.bind.DatatypeConverter;public class TestMD5 {public static void main(String[] args){for (String filepath : args) {String md5 = computeMD5(new File(filepath));System.out.println(md5);}}private static String computeMD5(File file) {DigestInputStream din = null;try {MessageDigest md5 = MessageDigest.getInstance("MD5");//第一个参数是一个输入流din = new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), md5);byte[] b = new byte[1024];while (din.read(b) != -1);byte[] digest = md5.digest();StringBuilder result = new StringBuilder(file.getName());result.append(": ");result.append(DatatypeConverter.printHexBinary(digest));return result.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (din != null) {din.close();}} catch (IOException e) {e.printStackTrace();}}return null;}
}

运行结果

修改 MD5 值

这里有两个图片,对它们进行合并,注意我这里的合并,不是通常所说的文件合并(例如合成九宫格图片),而是将文件的二进制数据合并。

先计算文件的 md5 值,注意下面的 Ahusky.jpeg 是上面的 husky.jpeg 的重命名,可以看出来对于md5值来说并没有变化,所以这是同一个文件。

然后将文件合并,这里用到的程序是我上面关于文件合并里面介绍的。可以进入了解详情,这里不再介绍了。

计算合并后文件的 md5 值

使用Java计算文件的MD5值(含修改MD5值的方法)相关推荐

  1. 【转】Java计算文件的hash值

    原文地址:http://blog.csdn.net/qq_25646191/article/details/78863110 如何知道一个文件是否改变了呢?当然是用比较文件hash值的方法,文件has ...

  2. Java计算文件的hash值

    如何知道一个文件是否改变了呢?当然是用比较文件hash值的方法,文件hash又叫文件签名,文件中哪怕一个bit位被改变了,文件hash就会不同. 比较常用的文件hash算法有MD5和SHA-1. 我用 ...

  3. 手机如何修改MD5视频?修改MD5视频的办法你清楚吗?

    手MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传 ...

  4. 小程序修改数组中对象的某个值或者修改对象值

    小程序中获取当前data定义的值,用this.data.xxx setData的时候要修改的值是不需要加this.data.xxx的,直接xxx, 一般直接修改data的值直接修改,修改数组中对象的值 ...

  5. 源生JS 之对象key值为数字时的取值及修改key值方法

    取值: 如果对象key值为数字使用.key(.0)无法取到对应值: 只需稍加修改obj.['0']即可取到对应值. 修改: 与取值同理: 打印效果对比处理前后: 可以看到将原始key值为0.1.2修改 ...

  6. java计算文件里的总分_java程序读取txt文件并计算总分 求帮忙

    展开全部 你这个不难,就是字符串处理, 你的文件修改下:每行两两元素636f70793231313335323631343130323136353331333332636336之间的空格用一个,如果超 ...

  7. Java 中 Boolean 和 boolean的默认值和修改默认值

    默认值 boolean 是 Java 的基本数据类型,默认值是false: Boolean 是 Java 的一个类,默认值是 null 使用推荐 根据阿里巴巴开发手册,在字段中推荐使用Boolean作 ...

  8. jsp页面input的value中的值含英文双引号处理方法

    jsp页面input的value值输出含英文双引号问题解决 在做Jsp页面开发时,我们经常使用JSTL表达式来进行页面的输出,但是突然遇到如下一个问题 问题描述:当数据库中某个字段带双引号时,inpu ...

  9. Word文件总页码不含首页和目录设置方法

    1. 按照常规设置节 2. 正文开始第一页节设置为不"链接到前一页眉" 3. 目录最后一个字符后插入书签 4. 在正文第一节页脚输入域代码,注意{}使用Ctrl F9输入 5. 效 ...

最新文章

  1. oracle学习总结二(转义字符)
  2. linux中why软件,why?why?why?
  3. java基础进阶一:String源码和String常量池
  4. JavaScript对象理解
  5. 鸿蒙可胜安卓,【鸿蒙币谈】币圈投资中八大见顶信号,让你抓住最佳买卖机会!...
  6. 看了50+竞品分析,我总结出5个常见问题和1套方法论
  7. 算法题存档20190304
  8. Linux平台提取DSDT,手动提取DSDT和SSDT教程
  9. 【MATLAB、深度学习】AlexNet及VGG神经网络在MATLAB上的应用
  10. Nhibernate出现No row with the given identifier exists问题的产生原因及解决方法
  11. 【LeetCode】【字符串】题号:*12. 整数转罗马数字
  12. ztree带有选项框的树形菜单使用
  13. linux进程管理实验视频,Linux进程管理实验
  14. 拉普拉斯变换转换简表
  15. FFMPEG硬件编解码器使用
  16. emoji表情包整理好的
  17. 【Android】组件安全
  18. Tomcat修改server.xml中的context标签后无法启动
  19. 你了解 JDK 8 Stream 数据流效率吗?千万级数据量性能如何?
  20. 计算机硬件系统-CPU中的寄存器

热门文章

  1. YUV12和YUV2格式
  2. 七牛云文件存储的使用【刘新宇】
  3. 用Excel制作不一样的百分比信息图表(2)
  4. UML中的9种图例解析
  5. [ZT] 戏言面向对象
  6. 刘未鹏之思维改变生活!
  7. 【译】关于 Go 代码结构的思考
  8. 小清新个人简历自我介绍PPT模板
  9. windows系统软件卸载方法
  10. 基于android公交车线路查询论文文献,基于Android手机的实时公交查询系统设计与实现...