Hashing mit dem SHA1-Algorithmus in C #


84

Ich möchte gegebenes byte[]Array mit der Verwendung von SHA1Algorithmus mit der Verwendung von hashen SHA1Managed.
Der byte[]Hash stammt aus dem Unit-Test.
Der erwartete Hash ist 0d71ee4472658cd5874c5578410a9d8611fc9aef(Groß- und Kleinschreibung beachten).

Wie kann ich das erreichen?

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

    }
}

1
Ihr erwarteter Hash ist ein hexadezimaler Wert, daher spielt es keine Rolle, ob zwischen Groß- und Kleinschreibung unterschieden wird, z. B.hex(e) == hex(E)
jAC

Antworten:


170

Für diejenigen, die eine "Standard" -Textformatierung des Hashs wünschen, können Sie Folgendes verwenden:

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

Dies erzeugt einen Hash wie 0C2E99D0949684278C30B9369B82638E1CEAD415.

Oder für eine Code-Golfversion:

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

Es stört mich, dass diese Lösung das SHA1Managed-Objekt nicht entsorgt, da es als Disposable markiert ist. Dieser Beitrag könnte bei der Optimierung hilfreich sein
sky-dev

@ sky-dev, dem stimme ich normalerweise zu IDisposable, aber ein kurzer Blick auf die Referenzquelle zeigt, dass in.Dispose()
Mitch

Ja, ich habe mir auch die Dispose-Implementierung angesehen. Es würde GarbageCollection nur ein bisschen beschleunigen. Es ist wahrscheinlich keine große Sache im großen Schema der Dinge.
Sky-Dev

21
@Mitch Wenn es die IDisposable-Schnittstelle implementiert, sollte es keine Rolle spielen, was in der Referenzquelle passiert. Sollten sie es jemals aus irgendeinem Grund so ändern, dass der Aufruf von .Dispose () wichtig wird, verursacht Ihr zuvor funktionierender Code jetzt ein Problem. Sich darauf zu verlassen, in die Eingeweide eines Gerüsts zu schauen, um festzustellen, womit Sie davonkommen können, ist ein Weg zu einem Wartungsalptraum. Ich empfehle dringend, die Dokumentation zu befolgen und Einweggegenstände richtig zu handhaben, um Ihnen langfristig Schmerzen zu ersparen.
unenthusiasticuser

2
@ijt, X2 weist es an, zwei hexadezimale Ziffern pro Byte zu verwenden. x2bedeutet Kleinbuchstaben, X2ist Großbuchstaben
Mitch

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

BEARBEITEN:

Sie können die Codierung auch beim Konvertieren des Byte-Arrays in einen String wie folgt angeben:

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

oder

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

Ich habe diese Codes schon einmal geschrieben, aber es hat nicht funktioniert. Ich kenne den Grund nicht
Merve Kaya,

1
Wenn sie einen Hex-String wollen, ist Base64 wahrscheinlich die falsche Wahl.
Joey

@Joey: Gegen die Antwort von GrantThomas gab das Mitglied an, dass sie einen String zurückgeben müssen
John Gathogo

@MerveKaya: Vielleicht solltest du erklären, was du mit "es hat nicht funktioniert" meinst. Was repräsentiert das eingehende Byte-Array? Wie haben Sie festgelegt, dass "SHA1Managed" - das Hashing des eingehenden Byte-Arrays 0d71ee4472658cd5874c5578410a9d8611fc9aefals Ausgabe erhalten soll?
John Gathogo

Byte [] Hash stammt aus dem Unit Test. In der Frage, die sie geschrieben haben, ist der erwartete Hash 0d71ee4472658cd5874c5578410a9d8611fc9aef. Es kommt vom Unit Test
Merve Kaya

15

Damit bin ich gegangen. Für diejenigen unter Ihnen, die optimieren möchten, besuchen Sie 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)));
        }
    }

Ich musste BitConverter.ToString (sha1.ComputeHash (Bytes)) verwenden. Ersetzen ("-", ""), da ich die von BitConverter eingeführten Bindestriche nicht wollte. Danach hat es wie ein Zauber funktioniert! Vielen Dank!
Sam

9

Der schnellste Weg ist folgender:

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

Für die Ausgabe kleiner Zeichen verwenden Sie x2anstelle vonX2


4
SHA1Managed implementiert IDisposable, daher möchten Sie es wahrscheinlich entsorgen, wenn Sie damit fertig sind, um Ressourcen freizugeben.
Rickythefox

8

Sie können "den Wert für das angegebene Byte-Array berechnen" mit ComputeHash:

var hash = sha1.ComputeHash(temp);

Wenn Sie das Ergebnis in Zeichenfolgendarstellung analysieren möchten, müssen Sie die Bytes mithilfe des {0:X2}Formatbezeichners formatieren.


4

Ich werde meinen Hut hier reinwerfen:

(als Teil einer statischen Klasse, da dieses Snippet zwei Erweiterungen enthält)

//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);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.