为什么 C# 和 Java 应用程序对同一个文件计算出不同的 MD5 值?
Why does C# and Java application calculate different MD5 values for the same file?
我有一个 C# 项目来验证文件的 MD5。我使用 System.Security.Cryptography.MD5
在 C# 中计算 MD5。
但与Java中的MD5不同。
编辑:我发现 C# 代码是正确的。感谢安迪。我可以知道如何更正 Java 代码吗?
C#代码:
public static String ComputeMD5(String fileName)
{
String hashMD5 = String.Empty;
if (System.IO.File.Exists(fileName))
{
using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
System.Security.Cryptography.MD5 calculator = System.Security.Cryptography.MD5.Create();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++){
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashMD5 = stringBuilder.ToString();
}
}
return hashMD5;
}
Java代码:
public static String ComputeMD5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = new byte[1024];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer, 0, 1024)) != -1) {
digest.update(buffer, 0, len);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bytesToHexString(digest.digest());
}
您的 bytesToHexString
函数有误。在使用 here 中的函数后,在这个完整的示例中,我得到与 Linux md5sum
命令和 Andy 建议的`onlinemd5.com 相同的结果。处理这个问题的最佳方法是使用一个库,例如 Apache Commons,它具有将字节转换为十六进制字符串的功能。这样,您就可以将工作转移到信誉良好的图书馆。
import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
public class Md5{
public static String computeMd5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = new byte[1024];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer, 0, 1024)) != -1) {
digest.update(buffer, 0, len);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return byteArrayToHex(digest.digest());
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
public static void main(String[] args){
System.out.println(computeMd5(new File("./text.txt")));
}
}
我有一个 C# 项目来验证文件的 MD5。我使用 System.Security.Cryptography.MD5
在 C# 中计算 MD5。
但与Java中的MD5不同。
编辑:我发现 C# 代码是正确的。感谢安迪。我可以知道如何更正 Java 代码吗?
C#代码:
public static String ComputeMD5(String fileName)
{
String hashMD5 = String.Empty;
if (System.IO.File.Exists(fileName))
{
using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
System.Security.Cryptography.MD5 calculator = System.Security.Cryptography.MD5.Create();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++){
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashMD5 = stringBuilder.ToString();
}
}
return hashMD5;
}
Java代码:
public static String ComputeMD5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = new byte[1024];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer, 0, 1024)) != -1) {
digest.update(buffer, 0, len);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bytesToHexString(digest.digest());
}
您的 bytesToHexString
函数有误。在使用 here 中的函数后,在这个完整的示例中,我得到与 Linux md5sum
命令和 Andy 建议的`onlinemd5.com 相同的结果。处理这个问题的最佳方法是使用一个库,例如 Apache Commons,它具有将字节转换为十六进制字符串的功能。这样,您就可以将工作转移到信誉良好的图书馆。
import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
public class Md5{
public static String computeMd5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = new byte[1024];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer, 0, 1024)) != -1) {
digest.update(buffer, 0, len);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return byteArrayToHex(digest.digest());
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
public static void main(String[] args){
System.out.println(computeMd5(new File("./text.txt")));
}
}