首页 > 解决方案 > ASP.NET Core - 在重负载下生成“000000 ...”sha256 哈希

问题描述

我有一个奇怪的问题。我在 ASP.NET Core 3.1 上运行 Web API。API 所做的一件事是从输入字符串生成 SHA256

private static HashAlgorithm algorithm = SHA256.Create();
public static byte[] GetSha256Hash(string inputString)
{
    return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

public static string GetSha256HashString(string inputString)
{
    var result = GetSha256Hash(inputString);
    // Return as hexadecimal string
    return string.Join(
        string.Empty,
        result.Select(x => x.ToString("x2")));
}


player.Id = GetSha256HashString($"{player.Name}-{player.Region}-{player.Country}");

在进行散列之前,我检查字段 player.Name、region 和 country 并且不为空。但有时,似乎主要发生在服务器负载过重(约 100 个请求/秒)时,它会生成一些请求(约 0.5%)

0000000000000000000000000000000000000000000000000000000000000000对于 player.id。通常它们看起来像这样a7da37b8a57ea714ec11f92c0025d6e654a483144eb68b829d388ea91eb81c79

即使所有字段都为空,仅三个破折号就可以确保不会发生这种情况。

我没有看到任何异常,我有点不知道如何调试它。欢迎任何帮助!让我知道是否需要添加更多信息。

环境:在 Linux 上的 Docker 中运行。

标签: c#.net-corehash

解决方案


您设置为的对象:

private static HashAlgorithm algorithm = SHA256.Create();

不是线程安全的。

在您的情况下,它实际上取决于访问器、实例或静态以及运行时(OS、netcore 等)

为了确保它确实可以正常工作,并且不会为同一源创建不同/错误的哈希值,您必须SHA256.Create()始终创建一个新的哈希值。

public static string GenerateSHA256(string input)
{
    var bytes = Encoding.Unicode.GetBytes(input);
    using (var hashEngine = SHA256.Create())
    {
        var hashedBytes = hashEngine.ComputeHash(bytes, 0, bytes.Length);
        var sb = new StringBuilder();
        foreach (var b in hashedBytes)
        {
            var hex = b.ToString("x2");
            sb.Append(hex);
        }
        return sb.ToString();
    }
}

您也可以在 Microsoft 的一些文档中找到它。

此类型的任何公共静态(在 Visual Basic 中为 Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。

.NET 小提琴

SO:实例成员线程不安全与公共静态

Git:关于这个话题的讨论


推荐阅读