我想计算Jobject的唯一哈希码。所以基于所以帖子我正在使用JTokenEqualityComparer.GetHashCode(JToken token)
方法来计算哈希码
[Fact]
public void GetHashcode()
{
JTokenEqualityComparer comp = new JTokenEqualityComparer();
// arrange
var obj1 = new JObject();
obj1.Add("FirstName", "foo");
obj1.Add("LastName", "bar");
var hashCode = comp.GetHashCode(obj1);
}
但是,每次我运行此单元测试时,它都会创建不同的哈希码。因此,看起来除了属性名称和属性值之外,它还使用其他东西来计算哈希代码。
我正在 ASP.NET 核心应用程序中使用此代码。它为具有相同属性和值的 JObjects 创建唯一的哈希代码,但是一旦应用程序池被回收,它就会为同一 JObject 创建新的哈希代码。
如何为具有相同属性和值的 JObject 创建唯一的哈希码?
因此,如果有 3 个具有相同属性和值的 JObjects 实例,它们的哈希码应该是相同的,无论计算哈希码的机器、时间和类如何。
你可以使用这样的东西。虽然我不确定,但从 JSON 的角度来看它是否是确定的 - 例如没有尝试数组。但我相信你一定能适应它。:)
[Fact]
public void GetHashcode() {
var o1 = new JObject();
o1.Add("FirstName", "foo");
o1.Add("LastName", "bar");
var o2 = new JObject();
o2.Add("Lorem", 123);
o2.Add("Ipsum", DateTime.Now.Date);
o1.Add("inner", o2);
var hashCode = ComputeHashCode(o1);
}
private static int ComputeHashCode(JToken value)
{
if (value is null)
{
return 0;
}
var queue = new Queue<JProperty>();
foreach (JProperty prop in value)
{
queue.Enqueue(prop);
}
if (queue.Count == 0)
{
return 0;
}
int hash = 17;
while (queue.Count > 0)
{
JProperty item = queue.Dequeue();
if (item.Value.HasValues)
{
foreach (JProperty prop in item.Value)
{
queue.Enqueue(prop);
}
}
else
{
// Hash code combination taken from here: https://stackoverflow.com/a/263416/8088324
unchecked
{
hash = hash * 23 + ComputeHashCodeCore(item.Name);
hash = hash * 23 + ComputeHashCodeCore(item.Value.ToString());
}
}
}
return hash;
}
// Stable hash code for string taken from here: https://stackoverflow.com/a/36845864/8088324
private static int ComputeHashCodeCore(string str)
{
unchecked
{
int hash1 = 5381;
int hash2 = hash1;
for (int i = 0; i < str.Length && str[i] != ' '; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ str[i];
if (i == str.Length - 1 || str[i + 1] == ' ')
break;
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
}
return hash1 + (hash2 * 1566083941);
}
}