我想使用Java来获得文件的MD5校验和。我真的很惊讶,但我还没有找到任何东西,显示如何获得一个文件的MD5校验和。
这是怎么做到的?
我想使用Java来获得文件的MD5校验和。我真的很惊讶,但我还没有找到任何东西,显示如何获得一个文件的MD5校验和。
这是怎么做到的?
当前回答
从其他答案中提取想法,这里有一个简单的代码,没有第三方依赖关系(或DatatypeConverter,在最新的jdk中更长),将其生成为与md5sum工具输出兼容的十六进制字符串:
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
...
static String calculateMD5(String path) throws IOException
{
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Files.readAllBytes(Paths.get(path)));
return String.format("%032x", new BigInteger(1, md.digest())); // hex, padded to 32 chars
} catch (NoSuchAlgorithmException ex)
{
throw new RuntimeException(ex); // MD5 is always available so this should be impossible
}
}
其他回答
谷歌guava提供了一个新的API。找到下面的一个:
public static HashCode hash(File file,
HashFunction hashFunction)
throws IOException
Computes the hash code of the file using hashFunction.
Parameters:
file - the file to read
hashFunction - the hash function to use to hash the data
Returns:
the HashCode of all of the bytes in the file
Throws:
IOException - if an I/O error occurs
Since:
12.0
com.google.common.hash API提供:
为所有哈希函数提供统一的用户友好的API murmur3的32位和128位种子实现 Md5()、sha1()、sha256()、sha512()适配器,只需更改一行代码就可以在这些适配器之间切换。 goodFastHash(int bits),用于当你不关心你使用什么算法时 HashCode实例的通用实用程序,如combineOrdered / combineUnordered
阅读用户指南(IO解释,哈希解释)。
对于您的用例,Files.hash()计算并返回文件的摘要值。
例如,sha-1摘要计算(将sha-1更改为MD5以获得MD5摘要)
HashCode hc = Files.asByteSource(file).hash(Hashing.sha1());
"SHA-1: " + hc.toString();
请注意,crc32比md5快得多,所以如果您不需要加密安全的校验和,请使用crc32。还要注意,md5不应该用来存储密码之类的东西,因为它很容易被暴力破解,对于密码,应该使用bcrypt、scrypt或sha-256来代替。
对于使用散列的长期保护,默克尔签名方案增加了安全性,由欧盟委员会赞助的后量子密码学研究小组建议使用这种密码技术来长期保护量子计算机(参考)。
请注意,crc32的碰撞率比其他的更高。
从其他答案中提取想法,这里有一个简单的代码,没有第三方依赖关系(或DatatypeConverter,在最新的jdk中更长),将其生成为与md5sum工具输出兼容的十六进制字符串:
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
...
static String calculateMD5(String path) throws IOException
{
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Files.readAllBytes(Paths.get(path)));
return String.format("%032x", new BigInteger(1, md.digest())); // hex, padded to 32 chars
} catch (NoSuchAlgorithmException ex)
{
throw new RuntimeException(ex); // MD5 is always available so this should be impossible
}
}
下面是一个简单的函数,它包装了Sunil的代码,以File作为参数。该函数不需要任何外部库,但需要Java 7。
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
public class Checksum {
/**
* Generates an MD5 checksum as a String.
* @param file The file that is being checksummed.
* @return Hex string of the checksum value.
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static String generate(File file) throws NoSuchAlgorithmException,IOException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(Files.readAllBytes(file.toPath()));
byte[] hash = messageDigest.digest();
return DatatypeConverter.printHexBinary(hash).toUpperCase();
}
public static void main(String argv[]) throws NoSuchAlgorithmException, IOException {
File file = new File("/Users/foo.bar/Documents/file.jar");
String hex = Checksum.generate(file);
System.out.printf("hex=%s\n", hex);
}
}
示例输出:
hex=B117DD0C3CBBD009AC4EF65B6D75C97B
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();