今天在做文件上传功能,需求要求相同内容的文件不能重复上传。感觉这个需求挺简单的,就给了一个刚入行的新同学。在合并代码的时候,发现这个同学居然以相同的文件名和相同的文件大小作为两个文件相同的依据。这个条件靠谱吗?从概率上来说,遇到两个同名同大小的文件的概率实在是太小了。这种判断在生产环境中可以稳定运行一段时间,但即使可能性很低,也是有可能的。如果能做到100%就好了。文件摘要验证相信同学们都下载过一些好心人开发的小工具。一些小工具会自带验证器,让你验证它提供的校验和值,防止有人恶意篡改小工具,保证小工具可以安心。使用。FileHashCheck如果两个文件有相同的内容,那么它们的摘要应该是相同的。这个原理能不能帮助我们识别两个文件是否相同呢?Java实现文件摘要带着这个疑问,我写了一个文件摘要提取工具类:/***提取文件校验和**@parampath文件完整路径*@paramalgorithm算法名例如MD5、SHA-1、SHA-256等*@returnCheckSum*@throwsnosuchalgorithMexectionThenoSuchalGorithMexception*@throwsioexioceptiontheioexection*/publicStaticsTringExtringChecksum(stringstringpath,stringalgorithm)=Files.readAllBytes(Paths.get(path));//摘要更新digest.update(fileBytes);//完成哈希摘要计算并返回特征值byte[]digested=digest.digest();//执行十六进制输出returnHexUtils.toHexString(digested);}接下来做几组对照实验来证明猜想。内容保持不变。首先,需要证明在内容不变的情况下,文件的摘要是否发生了变化。多次执行以下代码,断言始终为真。Stringpath="C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\application.yml";Stringchecksum=extractChecksum(path,"SHA-1");Stringhash="6bf4d6c101b4a7821226d3ec1f8d778a531bf265";Assertions.assertEquals(散列,校验和);而且我把文件名改成了application-dev.yml,连application-dev.txt的摘要都是一样的。我又改了下yml文件的内容,断言就变成了false。这证明在单个文件的情况下,内容不变,hash不变。文件复制我把yml文件复制了一份,改了文件名和类型,内容不变,保存到另一个目录下,测试他们的摘要有没有变化。Stringpath1="C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\application.yml";Stringpath2="C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\templates\\application-dev.txt";Stringchecksum1=extractChecksum(path1,"SHA-1");Stringchecksum2=extractChecksum(path2,"SHA-1");Stringhash="6bf4d6c101b4a7821226d3ec1f8d778a531bf265";Assertions.assertEquals(hash,checksum1);Assertions.assertEquals(hash,checksum2);结果,断言通过了,但是更改其中一个文件的内容后断言没有通过。新建一个空文件这里的新建空文件是指新创建的空文件,没有任何操作。新创建的空文件会根据特定的算法返回一个固定的值。例如,空文件在SHA-1算法下的值为:da39a3ee5e6b4b0d3255bfef95601890afd80709实验证明结论:在相同算法下,任何新创建的空文件的摘要值都是固定的。任何两个内容相同的文件,无论路径、文件名、文件类型如何,其摘要值都是相同的。文件的摘要值会随着文件内容的变化而变化。文件摘要的应用根据以上结论,文件摘要可以防止重复提交内容相同的文件。存储时,不仅要存储文件的路径,还要存储文件的汇总值。可能需要注意创建空文件的固定摘要问题。另外Java12中提供了一个新的API来处理文件内容重复的问题,有兴趣的可以研究一下。除了防篡改和去重,你知道文档摘要还有什么用处吗?欢迎留言讨论。本文转载自微信公众号“码农小胖哥”,可通过以下二维码关注。转载本文请联系码农小胖公众号。
