Как вы можете сгенерировать тот же MD5 Hashcode в С# и Java?
У меня есть функция, которая генерирует хеш MD5 в С# следующим образом:
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));
}
return sb.ToString();
В java моя функция выглядит так:
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(bytes,0,bytes.length);
String hashcode = new BigInteger(1,m.digest()).toString(16);
return hashcode;
В то время как код С# генерирует: "02945C9171FBFEF0296D22B0607D522D", java-коды генерируют: "5a700e63fa29a8eae77ebe0443d59239".
Есть ли способ генерировать один и тот же md5-хэш для одного и того же байта?
По запросу:
Это тестовый код в java:
File file = new File(System.getProperty("user.dir") + "/HashCodeTest.flv");
byte[] bytes = null;
try {
bytes = FileUtils.getBytesFromFile(file);
} catch (IOException e) {
fail();
}
try {
generatedHashCode = HashCode.generate(bytes);
} catch (NoSuchAlgorithmException e) {
fail();
}
и это мой код в С#
var blob = GetBlobByHttpPostedFile(httpPostedFile);
var hashCode = Md5Factory.ConvertByteArray(blob);
private static byte[] GetBlobByHttpPostedFile(HttpPostedFile httpPostedFile)
{
var contentLength = httpPostedFile.ContentLength;
var result = new byte[contentLength];
var inputStream = httpPostedFile.InputStream;
inputStream.Read(result, 0, contentLength);
return result;
}
Приветствия
Ответы
Ответ 1
Это должно быть хорошо - хотя вы могли бы сделать код Java проще, просто позвонив
byte[] digest = m.digest(bytes);
вместо вызова update
, затем digest
.
Вы абсолютно уверены, что у вас одинаковые данные в обоих случаях? Могли бы вы опубликовать примеры программ, показывающих, что это не удается с теми же жестко закодированными данными?
EDIT: Вот такой тест, о котором я думал. Эти две программы дают одинаковый результат:
С#:
using System;
using System.Security.Cryptography;
using System.Text;
class Test
{
static void Main()
{
byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("x2"));
}
Console.WriteLine(sb);
}
}
Java:
import java.math.BigInteger;
import java.security.MessageDigest;
public class Test
{
public static void main(String[] args) throws Exception
{
byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] digest = m.digest(bytes);
String hash = new BigInteger(1, digest).toString(16);
System.out.println(hash);
}
}
Ответ 2
Привет, я использую этот код, и он работает
Код С#:
public static string ConvertStringToMD5(string ClearText)
{
byte[] ByteData = Encoding.ASCII.GetBytes(ClearText);
//MD5 creating MD5 object.
MD5 oMd5 = MD5.Create();
//Hash değerini hesaplayalım.
byte[] HashData = oMd5.ComputeHash(ByteData);
//convert byte array to hex format
StringBuilder oSb = new StringBuilder();
for (int x = 0; x < HashData.Length; x++)
{
//hexadecimal string value
oSb.Append(HashData[x].ToString("x2"));
}
и код Java:
private String getMD5Digest(byte[] buffer) {
String resultHash = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] result = new byte[md5.getDigestLength()];
md5.reset();
md5.update(buffer);
result = md5.digest();
StringBuffer buf = new StringBuffer(result.length * 2);
for (int i = 0; i < result.length; i++) {
int intVal = result[i] & 0xff;
if (intVal < 0x10) {
buf.append("0");
}
buf.append(Integer.toHexString(intVal));
}
resultHash = buf.toString();
} catch (NoSuchAlgorithmException e) {
}
return resultHash;
}
Ответ 3
Я столкнулся с аналогичной проблемой, когда мы использовали Java MD5 Hash, чтобы определить, был ли обработан файл. Мы обнаружили, что мы не можем создать такой же хеш с использованием библиотеки .NET. Я попробовал все вышеперечисленное предложение, к сожалению, он не работает для меня.
Решение, которое я выяснил позже: вместо создания аналогичной функции в .NET мы вызываем функцию Java непосредственно в .NET. Существует один большой проект с открытым исходным кодом под названием Ja.NET. В основном, что я сделал: создайте класс Java, создающий хэш с использованием того же кода. скомпилируйте его с помощью Ja.NET javac. Затем, используя bam, скомпилируйте сгенерированный файл класса Java в DLL и используйте его в моем проекте .NET.
Ответ 4
Я знаю, что эта тема старая, но сейчас я столкнулся с той же проблемой и не смог найти ответ, который сработал у меня. Я писал патчер для игры и нуждался в файлах md5
hashcode
, чтобы гарантировать, что файлы обновлены, но С# и Java дали мне разные строки, хотя файлы были идентичными.
Вот как я его решил:
Код С#:
public static string getMD5(string fullPath)
{
MD5 md5 = MD5.Create();
using (FileStream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] hash = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int j = 0; j < hash.Length; j++)
{
sb.Append(hash[j].ToString("X2"));
}
return sb.ToString();
}
}
Это создает шестнадцатеричную строку с 32 символами. Apache Commons
DigestUtils.md5Hex(InputStream)
делает то же самое, теперь единственное отличие в том, что пример С# возвращает строку в верхнем регистре, поэтому решение просто конвертируется хэш из Java-программы в строку верхнего регистра.
Java-код:
public static String checkSumApacheCommons(String filePath)
{
String checksum = null;
try
{
checksum = DigestUtils.md5Hex(new FileInputStream(filePath));
}
catch (IOException ex)
{
ex.printStackTrace(System.out);
}
return checksum.toUpperCase();
}
Произведенные хеши выглядят как F674865D8A44695A2443017CFA2B0C67
.
Надеюсь, это поможет кому-то.