Visual C# を使用してハッシュ値を計算および比較する

この記事では、ハッシュ値を取得する方法と、2 つのハッシュ値を比較して、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. コードのusingSystemSystem.Security.Cryptography後半でこれらの名前空間からの宣言を修飾する必要がないように、 、、および System.Text 名前空間で ディレクティブを使用します。 これらのステートメントは、他の宣言の前に使用する必要があります。

    using System;
    using System.Security.Cryptography;
    using System.Text;
    
  4. ソース データを保持する文字列変数と、ソース バイトと結果のハッシュ値を保持する 2 バイト配列 (未定義のサイズ) を宣言します。

    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. クラスのインスタンスで を呼び出 ComputeHash して、ソース データの MD5 ハッシュを MD5CryptoServiceProvider 計算します。

    注:

    別のハッシュ値を計算するには、 クラスの別のインスタンスを作成する必要があります。

    //Compute hash based on source data.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  7. バイト配列は tmpHash 、ソース データの計算されたハッシュ値 (128 ビット値 = 16 バイト) を保持するようになりました。 多くの場合、このような値を 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. コードを保存して実行し、ソース値の結果の 16 進文字列を確認します。

2 つのハッシュ値を比較する

ソース データからハッシュを作成する目的は次のとおりです。

  • 時間の経過と同時にデータが変化したかどうかを確認する方法を提供します。
  • 実際の値を操作せずに 2 つの値を比較する。

どちらの場合も、2 つの計算されたハッシュを比較する必要があります。 どちらも 16 進文字列として格納されている場合は 、(上のセクションの最後の手順のように) 簡単です。 ただし、両方ともバイト配列の形式になる可能性があります。 次のコードは、前のセクションで作成したコードから続き、2 つのバイト配列を比較する方法を示しています。

  1. 16 進文字列の作成のすぐ下に、新しいソース データに基づいて新しいハッシュ値を作成します。

    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    byte[] tmpNewHash;
    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  2. 2 つのバイト配列を比較する最も簡単な方法は、配列をループして、各要素を 2 番目の値から対応する要素と比較することです。 要素が異なる場合、または 2 つの配列のサイズが同じでない場合、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. プロジェクトを保存して実行し、最初のハッシュ値から作成された 16 進文字列を表示します。 新しいハッシュが元のハッシュと等しいかどうかを確認します。

完全なコード一覧

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」を参照してください。