Использование Visual C# для вычисления и сравнения хэш-значений
В этой пошаговой статье показано, как получить хэш-значение и сравнить два хэш-значения с проверка, совпадают ли они с помощью Visual C#. В нем также представлен пример кода, показывающий, как выполнить эту задачу.
Исходная версия продукта: Visual C#
Оригинальный номер базы знаний: 307020
Сводка
В этой статье рассматриваются следующие пространства имен библиотеки классов Microsoft платформа .NET Framework:
System.Security.Cryptography
System.Text
Класс System.Security.Cryptography
в платформа .NET Framework упрощает вычисление хэш-значения для исходных данных.
Вычисление хэш-значения
С помощью криптографических ресурсов, содержащихся в System.Security.Cryptography
пространстве имен, легко создавать и сравнивать хэш-значения. Так как все хэш-функции принимают входные данные типа Byte[]
, может потребоваться преобразовать источник в массив байтов, прежде чем он будет хэширован. Чтобы создать хэш для строкового значения, выполните следующие действия.
Откройте Visual Studio .NET или Visual Studio.
Создание консольного приложения в Visual C# .NET или Visual C# создает открытый класс вместе с пустым
Main()
методом.Примечание.
В Visual C#. NET, Class1.cs создается по умолчанию. В Visual C# Program.cs создается по умолчанию.
Используйте директиву
using
System
для пространств имен ,System.Security.Cryptography
иSystem.Text
, чтобы позже в коде не требовалось определять объявления из этих пространств имен. Эти инструкции должны использоваться перед любыми другими объявлениями.using System; using System.Security.Cryptography; using System.Text;
Объявите строковую переменную для хранения исходных данных и два массива байтов (неопределенного размера) для хранения исходных байтов и полученного хэш-значения.
string sSourceData; byte[] tmpSource; byte[] tmpHash;
GetBytes()
Используйте метод класса ,System.Text.ASCIIEncoding
чтобы преобразовать исходную строку в массив байтов (требуется в качестве входных данных для функции хэширования).sSourceData = "MySourceData"; //Create a byte array from source data. tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
Вычислить хэш MD5 для исходных данных путем вызова
ComputeHash
для экземпляраMD5CryptoServiceProvider
класса .Примечание.
Чтобы вычислить другое хэш-значение, необходимо создать другой экземпляр класса .
//Compute hash based on source data. tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
Массив
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(); }
Сохраните и запустите код, чтобы просмотреть полученную шестнадцатеричную строку для исходного значения.
Сравнение двух хэш-значений
Цели создания хэша на основе исходных данных:
- Предоставление способа узнать, изменялись ли данные с течением времени.
- Сравнение двух значений без работы с фактическими значениями.
В любом случае необходимо сравнить два вычисляемых хэша. Это легко сделать, если они хранятся в виде шестнадцатеричных строк (как на последнем шаге выше). Но вполне возможно, что они оба будут в виде массивов байтов. В следующем коде, который продолжается из кода, созданного в предыдущем разделе, показано, как сравнить два массива байтов.
Сразу под созданием шестнадцатеричной строки создайте новое хэш-значение на основе новых исходных данных.
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();
Сохраните и запустите проект, чтобы просмотреть шестнадцатеричную строку, созданную из первого хэш-значения. Узнайте, равен ли новый хэш исходному.
Полный список кода
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 -1; i++)
{
sOutput.Append(arrInput[i].ToString("X2"));
}
return sOutput.ToString();
}
}
}
Ссылки
Дополнительные сведения об использовании криптографических функций платформа .NET Framework см. в разделе .NET.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по