C#でのSHA1アルゴリズムによるハッシュ


86

byte[]使用してSHA1アルゴリズムを使用して、指定された配列をハッシュしたいと思いSHA1Managedます。ハッシュはユニットテストから来ます。 予想されるハッシュは(大文字と小文字が区別されます)です。
byte[]
0d71ee4472658cd5874c5578410a9d8611fc9aef

どうすればこれを達成できますか?

public string Hash(byte [] temp)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {

    }
}

1
予期されるハッシュは16進値であるため、大文字と小文字が区別されるかどうかは関係ありません。例hex(e) == hex(E)
jAC 2013年

回答:


173

ハッシュの「標準」テキストフォーマットが必要な場合は、次のようなものを使用できます。

static string Hash(string input)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
        var sb = new StringBuilder(hash.Length * 2);

        foreach (byte b in hash)
        {
            // can be "x2" if you want lowercase
            sb.Append(b.ToString("X2"));
        }

        return sb.ToString();
    }
}

これにより、のようなハッシュが生成され0C2E99D0949684278C30B9369B82638E1CEAD415ます。

またはコードゴルフバージョンの場合:

static string Hash(string input)
{
    var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
    return string.Concat(hash.Select(b => b.ToString("x2")));
}

このソリューションは、Disposableとしてマークされているため、SHA1Managedオブジェクトを破棄しないというバグがあります。この投稿は最適化するときに便利です:stackoverflow.com/a/624379/991863
sky-dev

@ sky-dev、私は通常同意しますIDisposable、参照ソース短い旅行は興味深いことが何も起こらないことを示しています.Dispose()
Mitch

ええ、私はDisposeの実装も調べました。ガベージコレクションを少しスピードアップするだけです。それはおそらく物事の壮大な計画では大したことではありません。
sky-dev

21
@Mitch IDisposableインターフェースを実装している場合、参照ソースで何が起こるかは重要ではありません。.Dispose()呼び出しが重要になるなどの理由で変更された場合、以前に機能していたコードが問題を引き起こしています。フレームワークの腸を調べて何を回避できるかを判断することは、メンテナンスの悪夢への道です。ドキュメントに従い、使い捨てのオブジェクトを正しく処理することを強くお勧めします。長期的には痛みを軽減できます。
unenthusiasticuser 2016

2
@ ijt、X2は、バイトごとに2桁の16進数を使用するように指示します。 x2小文字を意味し、X2大文字です
Mitch

38
public string Hash(byte [] temp)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        var hash = sha1.ComputeHash(temp);
        return Convert.ToBase64String(hash);
    }
}

編集:

次のように、バイト配列を文字列に変換するときにエンコーディングを指定することもできます。

return System.Text.Encoding.UTF8.GetString(hash);

または

return System.Text.Encoding.Unicode.GetString(hash);

私は以前にこれらのコードを書いたが、それはうまくいかなかった。理由はわからない
Merve Kaya 2013

1
16進文字列が必要な場合は、Base64がおそらく間違った選択です。
ジョーイ

@Joey:GrantThomasからの回答に対して、メンバーは文字列を返す必要があることを示しました
John Gathogo 2013年

@MerveKaya:「うまくいかなかった」とはどういう意味か説明する必要があるかもしれません。着信バイト配列は何を表していますか?「SHA1Managed」をどのように決定し0d71ee4472658cd5874c5578410a9d8611fc9aefましたか?着信バイト配列をハッシュすると、出力として表示されますか?
John Gathogo 2013年

Byte []ハッシュはユニットテストから取得されます。彼らが書いた質問では、予想されるハッシュは0d71ee4472658cd5874c5578410a9d8611fc9aefです。それはユニットテストから来ています
Merve Kaya 2013

15

これは私が行ったものです。最適化したい方は、https://stackoverflow.com/a/624379/991863をご覧ください

    public static string Hash(string stringToHash)
    {
        using (var sha1 = new SHA1Managed())
        {
            return BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)));
        }
    }

BitConverterによってダッシュが導入されたくなかったので、BitConverter.ToString(sha1.ComputeHash(bytes))。Replace( "-"、 "")を使用する必要がありました。その後、それは魅力のように機能しました!ありがとう!
サム

9

最速の方法はこれです:

    public static string GetHash(string input)
    {
        return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("X2")).ToArray());
    }

x2代わりに小文字出力を使用する場合X2


4
SHA1ManagedはIDisposableを実装しているため、リソースを解放するためにIDisposableを使い終わったら破棄することをお勧めします。
rickythefox 2017年

8

以下を使用して、「指定されたバイト配列の値を計算する」ことができますComputeHash

var hash = sha1.ComputeHash(temp);

結果を文字列表現で分析する場合は、{0:X2}フォーマット指定子を使用してバイトをフォーマットする必要があります。


4

ここに帽子を投げます:

(このスニペットは2つの拡張機能であるため、静的クラスの一部として)

//hex encoding of the hash, in uppercase.
public static string Sha1Hash (this string str)
{
    byte[] data = UTF8Encoding.UTF8.GetBytes (str);
    data = data.Sha1Hash ();
    return BitConverter.ToString (data).Replace ("-", "");
}
// Do the actual hashing
public static byte[] Sha1Hash (this byte[] data)
{
    using (SHA1Managed sha1 = new SHA1Managed ()) {
    return sha1.ComputeHash (data);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.