使用 Visual C# 來計算和比較哈希值

本文說明如何取得哈希值,以及如何比較兩個哈希值,以檢查它們是否與 Visual C# 相同。 它也提供程式碼範例來示範如何執行這項工作。

原始產品版本: Visual C#
原始 KB 編號: 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在、 System.Security.CryptographySystem.Text 命名空間上使用 System指示詞,讓您不需要在程序代碼稍後限定來自這些命名空間的宣告。 這些語句必須在任何其他宣告之前使用。

    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. 在類別的MD5CryptoServiceProvider實例上呼叫 ComputeHash ,以計算源數據的 MD5 哈希。

    注意

    若要計算另一個哈希值,您必須建立 類別的另一個實例。

    //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