在 Java 中获取文件的 MD5 校验和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/304268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a File's MD5 Checksum in Java
提问by Hyman
I am looking to use Java to get the MD5 checksum of a file. I was really surprised but I haven't been able to find anything that shows how to get the MD5 checksum of a file.
我希望使用 Java 来获取文件的 MD5 校验和。我真的很惊讶,但我找不到任何显示如何获取文件的 MD5 校验和的内容。
How is it done?
它是如何完成的?
采纳答案by erickson
There's an input stream decorator, java.security.DigestInputStream
, so that you can compute the digest while using the input stream as you normally would, instead of having to make an extra pass over the data.
有一个输入流装饰器,java.security.DigestInputStream
这样您就可以像往常一样在使用输入流的同时计算摘要,而不必对数据进行额外的传递。
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"));
DigestInputStream dis = new DigestInputStream(is, md))
{
/* Read decorated stream (dis) to EOF as normal... */
}
byte[] digest = md.digest();
回答by Bill the Lizard
There's an example at Real's Java-How-tousing the MessageDigestclass.
Real 的 Java-How-to 中有一个使用MessageDigest类的示例。
Check that page for examples using CRC32 and SHA-1 as well.
检查该页面以获取使用 CRC32 和 SHA-1 的示例。
import java.io.*;
import java.security.MessageDigest;
public class MD5Checksum {
public static byte[] createChecksum(String filename) throws Exception {
InputStream fis = new FileInputStream(filename);
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
return complete.digest();
}
// see this How-to for a faster way to convert
// a byte array to a HEX string
public static String getMD5Checksum(String filename) throws Exception {
byte[] b = createChecksum(filename);
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return result;
}
public static void main(String args[]) {
try {
System.out.println(getMD5Checksum("apache-tomcat-5.5.17.exe"));
// output :
// 0bb2827c5eacf570b6064e24e0e6653b
// ref :
// http://www.apache.org/dist/
// tomcat/tomcat-5/v5.5.17/bin
// /apache-tomcat-5.5.17.exe.MD5
// 0bb2827c5eacf570b6064e24e0e6653b *apache-tomcat-5.5.17.exe
}
catch (Exception e) {
e.printStackTrace();
}
}
}
回答by Brian Gianforcaro
I recently had to do this for just a dynamic string, MessageDigest
can represent the hash in numerous ways. To get the signature of the file like you would get with the md5sumcommand I had to do something like the this:
我最近不得不为一个动态字符串执行此操作,MessageDigest
可以以多种方式表示散列。要像使用md5sum命令一样获得文件的签名,我必须执行以下操作:
try {
String s = "TEST STRING";
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(s.getBytes(),0,s.length());
String signature = new BigInteger(1,md5.digest()).toString(16);
System.out.println("Signature: "+signature);
} catch (final NoSuchAlgorithmException e) {
e.printStackTrace();
}
This obviously doesn't answer your question about how to do it specifically for a file, the above answer deals with that quiet nicely. I just spent a lot of time getting the sum to look like most application's display it, and thought you might run into the same trouble.
这显然不能回答您关于如何专门针对文件执行此操作的问题,上面的答案很好地解决了这个问题。我只是花了很多时间让总和看起来像大多数应用程序的显示一样,并认为您可能会遇到同样的问题。
回答by Leif Gruenwoldt
Use DigestUtilsfrom Apache Commons Codeclibrary:
使用DigestUtils从阿帕奇共享编解码器库:
try (InputStream is = Files.newInputStream(Paths.get("file.zip"))) {
String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(is);
}
回答by Matt Brock
If you're using ANT to build, this is dead-simple. Add the following to your build.xml:
如果您使用 ANT 进行构建,这非常简单。将以下内容添加到您的 build.xml:
<checksum file="${jarFile}" todir="${toDir}"/>
Where jarFile is the JAR you want to generate the MD5 against, and toDir is the directory you want to place the MD5 file.
其中 jarFile 是您要针对其生成 MD5 的 JAR,而 toDir 是您要放置 MD5 文件的目录。
回答by F.X
public static String MD5Hash(String toHash) throws RuntimeException {
try{
return String.format("%032x", // produces lower case 32 char wide hexa left-padded with 0
new BigInteger(1, // handles large POSITIVE numbers
MessageDigest.getInstance("MD5").digest(toHash.getBytes())));
}
catch (NoSuchAlgorithmException e) {
// do whatever seems relevant
}
}
回答by user552999
We were using code that resembles the code above in a previous post using
我们使用的代码类似于上一篇文章中的上述代码,使用
...
String signature = new BigInteger(1,md5.digest()).toString(16);
...
However, watch out for using BigInteger.toString()
here, as it will truncate leading zeros...
(for an example, try s = "27"
, checksum should be "02e74f10e0327ad868d138f2b4fdd6f0"
)
但是,请注意在BigInteger.toString()
此处使用,因为它会截断前导零...(例如, try s = "27"
, checksum 应该是"02e74f10e0327ad868d138f2b4fdd6f0"
)
I second the suggestion to use Apache Commons Codec, I replaced our own code with that.
我支持使用 Apache Commons Codec 的建议,我用它替换了我们自己的代码。
回答by oluies
The com.google.common.hashAPI offers:
该com.google.common.hashAPI提供:
- A unified user-friendly API for all hash functions
- Seedable 32- and 128-bit implementations of murmur3
- md5(), sha1(), sha256(), sha512() adapters, change only one line of code to switch between these, and murmur.
- goodFastHash(int bits), for when you don't care what algorithm you use
- General utilities for HashCode instances, like combineOrdered / combineUnordered
- 适用于所有哈希函数的统一用户友好 API
- murmur3 的可种子 32 位和 128 位实现
- md5(), sha1(), sha256(), sha512() 适配器,只需要修改一行代码就可以在这些之间切换,杂音。
- goodFastHash(int bits),当你不关心你使用什么算法时
- HashCode 实例的通用实用程序,如 combineOrdered / combineUnordered
Read the User Guide (IO Explained, Hashing Explained).
For your use-case Files.hash()
computes and returns the digest value for a file.
对于您的用例,Files.hash()
计算并返回文件的摘要值。
For example a sha-1digest calculation (change SHA-1 to MD5 to get MD5 digest)
例如sha-1摘要计算(将 SHA-1 更改为 MD5 以获得 MD5 摘要)
HashCode hc = Files.asByteSource(file).hash(Hashing.sha1());
"SHA-1: " + hc.toString();
Note that crc32is much faster than md5, so use crc32if you do not need a cryptographically secure checksum. Note also that md5should not be used to store passwords and the like since it is to easy to brute force, for passwords use bcrypt, scryptor sha-256instead.
请注意,crc32比md5快得多,因此如果您不需要加密安全校验和,请使用crc32。还要注意,md5不应该用于存储密码等,因为它很容易暴力破解,对于密码,请使用bcrypt、 scrypt或sha-256代替。
For long term protection with hashes a Merkle signature schemeadds to the security and The Post Quantum Cryptography Study Group sponsored by the European Commission has recommended use of this cryptography for long term protection against quantum computers (ref).
对于散列的长期保护, Merkle 签名方案增加了安全性,由欧盟委员会赞助的后量子密码学研究小组建议使用这种密码学来长期保护量子计算机(参考文献)。
Note that crc32has a higher collision rate than the others.
请注意,crc32的碰撞率高于其他的。
回答by Lukasz R.
Another implementation: Fast MD5 Implementation in Java
另一个实现:Java 中的快速 MD5 实现
String hash = MD5.asHex(MD5.getHash(new File(filename)));
回答by ColinD
Guavanow provides a new, consistent hashing API that is much more user-friendly than the various hashing APIs provided in the JDK. See Hashing Explained. For a file, you can get the MD5 sum, CRC32 (with version 14.0+) or many other hashes easily:
Guava现在提供了一个新的、一致的散列 API,它比 JDK 中提供的各种散列 API 更加用户友好。请参阅散列解释。对于文件,您可以轻松获得 MD5 总和、CRC32(版本 14.0+)或许多其他哈希值:
HashCode md5 = Files.hash(file, Hashing.md5());
byte[] md5Bytes = md5.asBytes();
String md5Hex = md5.toString();
HashCode crc32 = Files.hash(file, Hashing.crc32());
int crc32Int = crc32.asInt();
// the Checksum API returns a long, but it's padded with 0s for 32-bit CRC
// this is the value you would get if using that API directly
long checksumResult = crc32.padToLong();