Поделиться через


Использование Visual C# для вычисления и сравнения хэш-значений

В этой пошаговой статье показано, как получить хэш-значение и сравнить два хэш-значения, чтобы проверить, совпадают ли они с помощью Visual C#. Он также предоставляет пример кода, показывающий, как выполнить эту задачу.

Исходная версия продукта: Visual C#
Исходный номер базы знаний: 307020

Итоги

В этой статье рассматриваются следующие пространства имен библиотеки классов Microsoft платформа .NET Framework:

  • System.Security.Cryptography
  • System.Text

Класс System.Security.Cryptography в платформа .NET Framework упрощает вычисление хэш-значения для исходных данных.

Вычисление хэш-значения

Легко создавать и сравнивать хэш-значения с помощью криптографических ресурсов, содержащихся в System.Security.Cryptography пространстве имен. Так как все хэш-функции принимают входные данные типа Byte[], может потребоваться преобразовать источник в массив байтов, прежде чем он хэширован. Чтобы создать хэш для строкового значения, выполните следующие действия.

  1. Откройте Visual Studio .NET или Visual Studio.

  2. Создайте консольное приложение в Visual C# .NET или в Visual C# создает общедоступный класс вместе с пустым Main() методом.

    Примечание.

    В Visual C#. NET, Class1.cs создается по умолчанию. В Visual C# Program.cs создается по умолчанию.

  3. using Используйте директиву для SystemSystem.Security.Cryptographyпространств имен и System.Text пространств имен, чтобы вы не должны квалифицировать объявления из этих пространств имен позже в коде. Эти инструкции необходимо использовать перед любыми другими объявлениями.

    using System;
    using System.Security.Cryptography;
    using System.Text;
    
  4. Объявите строковую переменную для хранения исходных данных и двух массивов байтов (неопределенного размера) для хранения исходных байтов и результирующего хэш-значения.

    string sSourceData;
    byte[] tmpSource;
    byte[] tmpHash;
    
  5. GetBytes() Используйте метод System.Text.ASCIIEncoding класса, чтобы преобразовать исходную строку в массив байтов (требуется в качестве входных данных для функции хэширования).

    sSourceData = "MySourceData";
    //Create a byte array from source data.
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    
  6. Вычислить хэш MD5 для исходных данных путем вызова ComputeHash экземпляра MD5CryptoServiceProvider класса.

    Примечание.

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

    //Compute hash based on source data.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  7. Теперь tmpHash массив байтов содержит вычисляемое хэш-значение (128-разрядное значение=16 байт) для исходных данных. Часто полезно отображать или хранить такое значение в виде шестнадцатеричной строки, которая выполняет следующий код:

    Console.WriteLine(ByteArrayToString(tmpHash));
    static string ByteArrayToString(byte[] arrInput)
    {
        int i;
        StringBuilder sOutput = new StringBuilder(arrInput.Length);
        for (i=0;i < arrInput.Length; i++)
        {
            sOutput.Append(arrInput[i].ToString("X2"));
        }
        return sOutput.ToString();
    }
    
  8. Сохраните и запустите код, чтобы просмотреть результирующая шестнадцатеричная строка для исходного значения.

Сравнение двух хэш-значений

Цели создания хэша из исходных данных:

  • Предоставление способа узнать, изменились ли данные с течением времени.
  • Сравнение двух значений без работы с фактическими значениями.

В любом случае необходимо сравнить два вычисляемых хэша. Это легко, если они хранятся как шестнадцатеричные строки (как и в последнем шаге выше). Но возможно, что они оба будут в виде массивов байтов. Следующий код, который продолжается из кода, созданного в предыдущем разделе, показывает, как сравнить два массива байтов.

  1. Под созданием шестнадцатеричной строки создайте новое хэш-значение на основе новых исходных данных.

    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    byte[] tmpNewHash;
    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  2. Самый простой способ сравнения двух массивов байтов заключается в цикле по массивам, сравнивая каждый отдельный элемент со своим аналогом из второго значения. Если какие-либо элементы отличаются, или если два массива не одинаковы, эти два значения не равны.

    bool bEqual = false;
    if (tmpNewHash.Length == tmpHash.Length)
    {
        int i=0;
        while ((i < tmpNewHash.Length) && (tmpNewHash[i] == tmpHash[i]))
        {
            i += 1;
        }
        if (i == tmpNewHash.Length)
        {
            bEqual = true;
        }
    }
    
    if (bEqual)
        Console.WriteLine("The two hash values are the same");
    else
        Console.WriteLine("The two hash values are not the same");
    Console.ReadLine();
    
  3. Сохраните и запустите проект, чтобы просмотреть шестнадцатеричную строку, созданную из первого хэш-значения. Узнайте, равен ли новый хэш исходному.

Полный листинг кода

using System;
using System.Security.Cryptography;
using System.Text;

namespace ComputeAHash_csharp
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        static void Main(string[] args)
        {
            string sSourceData;
            byte[] tmpSource;
            byte[] tmpHash;
            sSourceData = "MySourceData";
            //Create a byte array from source data
            tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

            //Compute hash based on source data
            tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
            Console.WriteLine(ByteArrayToString(tmpHash));

            sSourceData = "NotMySourceData";
            tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

            byte[] tmpNewHash;

            tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);

            bool bEqual = false;
            if (tmpNewHash.Length == tmpHash.Length)
            {
                int i=0;
                while ((i < tmpNewHash.Length) && (tmpNewHash[i] == tmpHash[i]))
                {
                    i += 1;
                }
                if (i == tmpNewHash.Length)
                {
                    bEqual = true;
                }
            }

            if (bEqual)
                Console.WriteLine("The two hash values are the same");
            else
                Console.WriteLine("The two hash values are not the same");
            Console.ReadLine();
        }

        static string ByteArrayToString(byte[] arrInput)
        {
            int i;
            StringBuilder sOutput = new StringBuilder(arrInput.Length);
            for (i=0;i < arrInput.Length; i++)
            {
                sOutput.Append(arrInput[i].ToString("X2"));
            }
            return sOutput.ToString();
        }
    }
}

Ссылки

Дополнительные сведения об использовании криптографических функций платформа .NET Framework см. в .NET.