我有一个奇怪的问题。我正在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,区域和国家,并且不为null。但有时,大多数情况似乎是在服务器负载较重(约100个请求/秒)时发生的,对于服务器生成的一些请求(约0.5%),它会发生
0000000000000000000000000000000000000000000000000000000000000000
for player.id。通常他们看起来像这样a7da37b8a57ea714ec11f92c0025d6e654a483144eb68b829d388ea91eb81c79
即使所有字段都为空,仅三个破折号也将确保不会发生这种情况。
我没有看到任何例外,我对如何调试它有点想法。欢迎任何帮助!让我知道是否需要添加更多信息。
Env:在Linux上的Docker中运行。
您要设置为的对象:
private static HashAlgorithm algorithm = SHA256.Create();
不是线程安全的。
在您的case中,实际上是depends on the accessor, instance or static and also the runtime (OS, netcore, etc.)
为了确保它确实可以正常工作而不会遇到麻烦,并且不会为相同的源创建不同的/错误的哈希,您必须始终要创建哈希来创建新的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)成员都是线程安全。不保证任何实例成员都是线程安全。
public static string GetSha256HashString(string inputString)
{
SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
byte[] B1;
byte[] B2;
B1 = UTF8Encoding.UTF8.GetBytes(inputString.Trim());
B2 = sha256.ComputeHash(B1);
string HashString = BitConverter.ToString(B2);
return HashString;
}