Udostępnij za pośrednictwem


Używanie języka Visual C# do obliczania i porównywania wartości skrótu

W tym artykule krok po kroku pokazano, jak uzyskać wartość skrótu i jak porównać dwie wartości skrótu, aby sprawdzić, czy są identyczne przy użyciu języka Visual C#. Zawiera również przykładowy kod pokazujący, jak wykonać to zadanie.

Oryginalna wersja produktu: Visual C#
Oryginalny numer KB: 307020

Podsumowanie

W tym artykule opisano następujące przestrzenie nazw biblioteki klas programu Microsoft .NET Framework:

  • System.Security.Cryptography
  • System.Text

Klasa System.Security.Cryptography w programie .NET Framework ułatwia obliczanie wartości skrótu dla danych źródłowych.

Obliczanie wartości skrótu

Łatwo jest wygenerować i porównać wartości skrótu przy użyciu zasobów kryptograficznych zawartych w System.Security.Cryptography przestrzeni nazw. Ponieważ wszystkie funkcje skrótu przyjmują dane wejściowe typu Byte[], może być konieczne przekonwertowanie źródła na tablicę bajtów przed jej skrótem. Aby utworzyć skrót dla wartości ciągu, wykonaj następujące kroki:

  1. Otwórz program Visual Studio .NET lub Visual Studio.

  2. Utwórz nową aplikację konsolową na platformie .NET w języku Visual C# lub w języku Visual C# tworzy klasę publiczną wraz z pustą Main() metodą.

    Uwaga 16.

    W języku Visual C#. Platforma NET, Class1.cs jest tworzona domyślnie. W języku Visual C# Program.cs jest tworzony domyślnie.

  3. using Użyj dyrektywy w Systemprzestrzeniach nazw , System.Security.CryptographyiSystem.Text, aby nie być wymagane do kwalifikowania deklaracji z tych przestrzeni nazw w dalszej części kodu. Te instrukcje muszą być używane przed wszelkimi innymi deklaracjami.

    using System;
    using System.Security.Cryptography;
    using System.Text;
    
  4. Zadeklaruj zmienną ciągu do przechowywania danych źródłowych i dwie tablice bajtów (o niezdefiniowanym rozmiarze) do przechowywania bajtów źródłowych i wynikowej wartości skrótu.

    string sSourceData;
    byte[] tmpSource;
    byte[] tmpHash;
    
  5. GetBytes() Użyj metody System.Text.ASCIIEncoding klasy, aby przekonwertować ciąg źródłowy na tablicę bajtów (wymagane jako dane wejściowe funkcji tworzenia skrótów).

    sSourceData = "MySourceData";
    //Create a byte array from source data.
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    
  6. Oblicz skrót MD5 dla danych źródłowych, wywołując ComputeHash wystąpienie MD5CryptoServiceProvider klasy .

    Uwaga 16.

    Aby obliczyć inną wartość skrótu, należy utworzyć kolejne wystąpienie klasy.

    //Compute hash based on source data.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  7. Tablica tmpHash bajtów zawiera teraz obliczoną wartość skrótu (128-bitową wartość=16 bajtów) dla danych źródłowych. Często warto wyświetlać lub przechowywać taką wartość jako ciąg szesnastkowy, który wykonuje następujący kod:

    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. Zapisz, a następnie uruchom kod, aby wyświetlić wynikowy ciąg szesnastkowy dla wartości źródłowej.

Porównanie dwóch wartości skrótu

Cele tworzenia skrótu na podstawie danych źródłowych to:

  • Zapewnienie sposobu sprawdzenia, czy dane uległy zmianie w czasie.
  • Porównywanie dwóch wartości bez pracy z rzeczywistymi wartościami.

W obu przypadkach należy porównać dwa obliczone skróty. Jest to łatwe, jeśli są one przechowywane jako ciągi szesnastkowe (jak w ostatnim kroku powyższej sekcji). Ale możliwe, że oba będą miały postać tablic bajtów. Poniższy kod, który jest kontynuowany z kodu utworzonego w poprzedniej sekcji, pokazuje, jak porównać dwie tablice bajtów.

  1. Tuż poniżej tworzenia ciągu szesnastkowego utwórz nową wartość skrótu na podstawie nowych danych źródłowych.

    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    byte[] tmpNewHash;
    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  2. Najprostszym sposobem porównania dwóch tablic bajtów jest pętla przez tablice, porównując poszczególne elementy z jego odpowiednikiem z drugiej wartości. Jeśli jakiekolwiek elementy są różne lub jeśli dwie tablice nie mają tego samego rozmiaru, te dwie wartości nie są równe.

    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. Zapisz, a następnie uruchom projekt, aby wyświetlić ciąg szesnastkowy utworzony na podstawie pierwszej wartości skrótu. Sprawdź, czy nowy skrót jest równy oryginalnemu.

Kompletna lista kodu

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();
        }
    }
}

Informacje

Aby uzyskać więcej informacji na temat używania funkcji kryptograficznych programu .NET Framework, zobacz .NET.