Я перевожу старую программу на новую версию (консольное приложение в WPF) и сталкиваюсь с проблемой хеша md5. Это программа импорта (беру XML, сериализую ее, преобразую данные и сохраняю в БД).Чтобы избежать дублирования данных, перед импортом я установил хеш объекта, чтобы проверить, существуют ли данные.Эта консольная программа устарела и удобна для пользователя, не являющегося ИТ-специалистом, поэтому мне нужно поместить ее в версию WPF, которая будет проще в использовании :) НО!Когда я спрашиваю хэш, я получаю другой результат> _ <</p>
Как это работает:
Я читаю узел XML
Я создаю объект (кстати, телевизионная программа)
Когда я взял все из xml, я создаю специальную HashModel (класс, содержащий только данные, которые я хочу проверить,поэтому я вырезал все значения даты / времени / ..., у меня есть только заголовок, резюме, .... только данные, которые не могут быть изменены)
- Я вызываю функцию GenerateKey (см. после) с объектом HashModel и установите его в исходном объекте:
- ProgramHashModel phm = new ProgramHashModel (prog);
- prog.ImportId = ProgramHashLib.GenerateKey (phm);
Все это работает хорошо, но я получаю другой результат между консолью и WPF ...
Версии фреймворка:
- Консоль: 3.5
- WPF 4.6.1
- Библиотека (с хешем): 2.0
Я пытался получить хэш каждого члена объекта (ProgramHashLib.GenerateKey (phm.Casting) на примере), и я получил одинаковый результат в каждой версии ... поэтому я не думаю, что Framework несет ответственность ... Я проверил все элементы объекта, и они были одинаковыми...
открытый абстрактный класс ProgramHashLib {public static String GenerateKey (Object sourceObject) {String hashString;
//Catch unuseful parameter values
if (sourceObject == null)
{
throw new ArgumentNullException("Null as parameter is not allowed");
}
else
{
//We determine if the passed object is really serializable.
try
{
//Now we begin to do the real work.
hashString = ComputeHash(ObjectToByteArray(sourceObject));
return hashString;
}
catch (AmbiguousMatchException ame)
{
throw new ApplicationException("Could not definitely decide if object is serializable. Message:" + ame.Message);
}
}
}
private static string ComputeHash(byte[] objectAsBytes)
{
MD5 md5 = new MD5CryptoServiceProvider();
try
{
byte[] result = md5.ComputeHash(objectAsBytes);
// Build the final string by converting each byte
// into hex and appending it to a StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));
}
// And return it
return sb.ToString();
}
catch (ArgumentNullException ane)
{
//If something occurred during serialization,
//this method is called with a null argument.
Console.WriteLine("Hash has not been generated.");
return null;
}
}
private static readonly Object locker = new Object();
private static byte[] ObjectToByteArray(Object objectToSerialize)
{
MemoryStream fs = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
try
{
//Here's the core functionality! One Line!
//To be thread-safe we lock the object
lock (locker)
{
formatter.Serialize(fs, objectToSerialize);
}
return fs.ToArray();
}
catch (SerializationException se)
{
Console.WriteLine("Error occurred during serialization. Message: " + se.Message);
return null;
}
finally
{
fs.Close();
}
}
}