Мой MD5 Hash объекта дает мне другой результат в зависимости от программы, которая его вызывает - PullRequest
0 голосов
/ 21 января 2019

Я перевожу старую программу на новую версию (консольное приложение в 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();
        }
    }
}

1 Ответ

0 голосов
/ 21 января 2019

ОК!Так что это была проблема со структурой.Я установил WPF на 3.5, и все было в порядке. Мне просто пришлось повторить некоторые функции:

  • await / async не работает в 3.5, поэтому ищите и находите AsyncBridge для 3.5 ...
  • FileHelpers остановил компиляцию, поэтому я был вынужден использовать 2.0 вместо 3.5

Я не очень доволен понижением рейтинга, но это работает по крайней мере: (

Спасибо всем, кто прочитал это и попытался мне помочь! :) 1011 *

...