在C#中使用SHA1算法进行哈希处理


84

我想byte[]通过使用SHA1算法对给定数组进行哈希处理SHA1Managed
byte[]散列将来自单元测试。
预期的哈希是0d71ee4472658cd5874c5578410a9d8611fc9aef(区分大小写的)。

我该如何实现?

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

    }
}

1
您期望的哈希值是一个十六进制值,因此它是否区分大小写无关紧要,例如hex(e) == hex(E)
jAC 2013年

Answers:


170

对于那些想要哈希的“标准”文本格式的用户,可以使用如下所示的内容:

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

令我感到困惑的是,此解决方案没有处理SHA1Managed对象,因为它被标记为Disposable。优化时,此帖子可能会很方便:stackoverflow.com/a/624379/991863
sky-dev

@ sky-dev,我通常会同意IDisposable,但是快速浏览参考资料表明,.Dispose()
Mitch

是的,我也查看了Dispose实现。这只会加快GarbageCollection的速度。在宏大的计划中,这可能并不重要。
sky-dev

21
@Mitch如果它实现IDisposable接口,则在引用源中发生的情况无关紧要。如果他们出于任何原因更改了它,以至于.Dispose()调用变得很重要,则您以前的工作代码现在会引起问题。依靠调查框架的内容来确定可以避免的事情是维护噩梦的途径。我强烈建议您遵循文档并正确处理一次性物品,从长远来看,这将避免您的痛苦。
unenthusiasticuser 2016年

2
@ ijt,X2告诉它每个字节使用两个十六进制数字。 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);

我写这些代码之前,但它没有工作,我不知道原因
梅尔韦卡亚

1
如果他们想要一个十六进制字符串,那么Base64可能是错误的选择。
乔伊

@Joey:反对GrantThomas的回答,该成员表示,他们需要返回一个字符串
John Gathogo 2013年

@MerveKaya:也许您应该解释“它没有用”的含义。传入的字节数组代表什么?您如何确定“ SHA1Managed”-散列传入的字节数组应为您0d71ee4472658cd5874c5578410a9d8611fc9aef提供输出?
John Gathogo 2013年

Byte []哈希来自单元测试。在问题中,他们写道,预期的哈希为0d71ee4472658cd5874c5578410a9d8611fc9aef。它来自单元测试
Merve Kaya

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.ToString(sha1.ComputeHash(bytes))。Replace(“-”,“”),因为我不想使用BitConverter引入的破折号。之后,它就像一个魅力!谢谢!
山姆

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,因此您可能希望在完成处理后将其处置以释放资源。
rickythefox

8

您可以使用以下命令“计算指定字节数组的值” ComputeHash

var hash = sha1.ComputeHash(temp);

如果要以字符串表示形式分析结果,则需要使用{0:X2}格式说明符格式化字节。


4

我将帽子戴在这里:

(作为静态类的一部分,因为此代码段是两个扩展)

//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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.