Хеширование нескольких байтов [] в один хеш с помощью C #? - PullRequest
10 голосов
/ 27 апреля 2011

У меня есть три поля: string Title, byte[] Body и byte[] Data, из которых я хочу вычислить один хеш в качестве проверки, чтобы убедиться, что они не были подделаны или повреждены.

В Python я могу использовать md5.update() несколько раз подряд для выполнения этого. Но я не могу найти аналогичные возможности в C #. Чтобы использовать MD5.ComputeHash (), мне нужно скопировать все мои источники в один байт [], что я бы хотел избежать.

Как я могу объединить все это в один хэш, не копируя данные во временный буфер?

Ответы [ 6 ]

15 голосов
/ 27 апреля 2011

Почти все алгоритмы хеширования разработаны таким образом, что они могут последовательно передаваться с данными в нескольких блоках.Результат такой же, как если бы все данные были хэшированы одновременно.

Создайте экземпляр, например, MD5CryptoServiceProvider и вызовите метод TransformBlock для каждого блока и Метод TransformFinalBlock для последнего блока:

MD5 md5 = new MD5CryptoServiceProvider();

// For each block:
md5.TransformBlock(block, 0, block.Length, block, 0);

// For last block:
md5.TransformFinalBlock(block, 0, block.Length);

// Get the hash code
byte[] hash = md5.Hash;
3 голосов
/ 01 сентября 2018

Существует также решение в .Net Standard и .Net Core с использованием IncrementalHash

IncrementalHash md5 = IncrementalHash.Create(HashAlgorithmName.MD5)

// For each block:
md5.AppendData(block);

// Get the hash code
byte[] hash = md5.GetHashAndReset();
0 голосов
/ 27 апреля 2011

Вызов функции ComputeHash для трех разных значений приведет к созданию трех разных результатов байтового массива.Затем эти результаты должны быть каким-то образом объединены для получения одного хэша.Нет никакого способа обойти этот факт.Это создаст три новых объекта в куче.Он будет вычислять хеш (довольно медленная операция) три раза вместо одного.

Я думаю, что наиболее эффективный способ сделать то, что вы хотите, - это просто скопировать исходные значения в один байтовый массив и взять его хеш.

Вы не говоритепочему вы хотите избежать такого подхода.Я думаю, что это выигрывает с точки зрения простоты и ремонтопригодности.Это самодокументированный, очевидный подход.Это самый эффективный метод.Я не вижу обратной стороны.

0 голосов
/ 27 апреля 2011

вы можете создать хэш над значениями хеша.

MD5 md5 =  System.Security.Cryptography.MD5.Create();
byte[] totalHash= md5.ComputeHash(md5.ComputeHash(part1).Concat(md5t.computeHash(part2)));

не создает копию байтового массива, но хэширует конкатенацию хэшей.

0 голосов
/ 27 апреля 2011

Используя обычный .NET, я не думаю, что есть способ обновить и MD5-хэш. Однако в Windows есть функция MD5Update , определенная в crypt.dll. Вы могли бы использовать Interop, чтобы использовать это, я полагаю.

В противном случае есть реализация PHP-эквивалента в .NET c #, расположенная здесь на SO: Проблема с переносом функции PHP crypt () на C #

PS: Я бы определенно выбрал комбинированное решение для временных переменных: -)

0 голосов
/ 27 апреля 2011

Вы должны объединить их все в одну переменную и затем вычислить хеш MD5. Я не вижу там никаких ярлыков.

Видите ли, большинство решений, предлагаемых здесь, просто пытаются выполнить несколько команд в одной строке ("один вкладыш") или реализовать что-то, чтобы "под капотом" объединить ваши поля, а затем хэш ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...