Пример хеширования C # MD5 - PullRequest
12 голосов
/ 06 мая 2009

Редактировать: Я переименовал это в пример, так как код работает, как ожидалось.

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

File.Copy(pathSrc, pathDest, true);

String md5Result;
StringBuilder sb = new StringBuilder();
MD5 md5Hasher = MD5.Create();

using (FileStream fs = File.OpenRead(pathDest))
{
    foreach(Byte b in md5Hasher.ComputeHash(fs))
        sb.Append(b.ToString("x2").ToLower());
}

md5Result = sb.ToString();

File.Delete(pathDest);

Я получаю исключение «процесс не может получить доступ к файлу» на File.Delete().

Я ожидаю, что с оператором using поток файлов будет красиво закрыт. Я также попытался объявить файловый поток отдельно, удалив using и поставив fs.Close() и fs.Dispose() после чтения.

После этого я прокомментировал фактические вычисления md5, и код оправдывает удаление файла, так что похоже, что это как-то связано с ComputeHash(fs).

Ответы [ 6 ]

20 голосов
/ 10 декабря 2012

Импорт пространства имен

using System.Security.Cryptography;

Вот функция, которая возвращает вам хэш-код md5. Вам необходимо передать строку в качестве параметра.

public static string GetMd5Hash(string input)
{
        MD5 md5Hash = MD5.Create();
        // Convert the input string to a byte array and compute the hash.
        byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

        // Create a new Stringbuilder to collect the bytes
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data 
        // and format each one as a hexadecimal string.
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

        // Return the hexadecimal string.
        return sBuilder.ToString();
}
15 голосов
/ 06 мая 2009

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

Какую версию .NET вы используете?

Я помещаю имеющийся у меня код, который работает здесь, и если вы поместите его в консольное приложение в VS2008 .NET 3.5 sp1, он будет работать без ошибок (по крайней мере для меня).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace lockTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string hash = GetHash("lockTest.pdb");

            Console.WriteLine("Hash: {0}", hash);

            Console.ReadKey();
        }

        public static string GetHash(string pathSrc)
        {
            string pathDest = "copy_" + pathSrc;

            File.Copy(pathSrc, pathDest, true);

            String md5Result;
            StringBuilder sb = new StringBuilder();
            MD5 md5Hasher = MD5.Create();

            using (FileStream fs = File.OpenRead(pathDest))
            {
                foreach (Byte b in md5Hasher.ComputeHash(fs))
                    sb.Append(b.ToString("x2").ToLower());
            }

            md5Result = sb.ToString();

            File.Delete(pathDest);

            return md5Result;
        }
    }
}
1 голос
/ 06 мая 2009

Вы тоже пытались обернуть свой объект MD5 в использование ()? Из документов MD5 является одноразовым. Это может заставить его отказаться от файла.

0 голосов
/ 06 мая 2009

md5hasher.Clear () после того, как ваш цикл может добиться цели.

0 голосов
/ 06 мая 2009

Почему бы не открыть файл с помощью FileShare.ReadWrite?

0 голосов
/ 06 мая 2009

Вы пытались установить md5Hasher в null перед удалением файла? Вероятно, к FileStream все еще привязан дескриптор (возможно, утечка памяти).

...