byte[] 数组上的 GetHashCode()

问题描述 投票:0回答:6

GetHashCode()
数组上调用时,
byte[]
会计算什么? 具有相同内容的 2 个数据数组不提供相同的哈希值。

c# hash
6个回答
79
投票
.NET 中的数组不会覆盖

Equals

GetHashCode
,因此您将获得的值基本上基于引用相等(即 
Object
 中的默认实现) - 为了实现值相等,您需要滚动您自己的代码(或从第三方找到一些代码)。如果您尝试使用字节数组作为字典等中的键,您可能需要实现 
IEqualityComparer<byte[]>

编辑:这是一个可重用的数组相等比较器,只要数组元素正确处理相等性就应该没问题。请注意,在将数组用作字典中的键后,您一定不能对其进行变异,否则即使使用相同的引用,您也将无法再次找到它。

using System; using System.Collections.Generic; public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]> { // You could make this a per-instance field with a constructor parameter private static readonly EqualityComparer<T> elementComparer = EqualityComparer<T>.Default; public bool Equals(T[] first, T[] second) { if (first == second) { return true; } if (first == null || second == null) { return false; } if (first.Length != second.Length) { return false; } for (int i = 0; i < first.Length; i++) { if (!elementComparer.Equals(first[i], second[i])) { return false; } } return true; } public int GetHashCode(T[] array) { unchecked { if (array == null) { return 0; } int hash = 17; foreach (T element in array) { hash = hash * 31 + elementComparer.GetHashCode(element); } return hash; } } } class Test { static void Main() { byte[] x = { 1, 2, 3 }; byte[] y = { 1, 2, 3 }; byte[] z = { 4, 5, 6 }; var comparer = new ArrayEqualityComparer<byte>(); Console.WriteLine(comparer.GetHashCode(x)); Console.WriteLine(comparer.GetHashCode(y)); Console.WriteLine(comparer.GetHashCode(z)); Console.WriteLine(comparer.Equals(x, y)); Console.WriteLine(comparer.Equals(x, z)); } }

与其他非原始内置类型一样,它只返回任意值。它绝对不会尝试对数组的内容进行哈希处理。请参阅

23
投票

简单的解决方案

15
投票
public static int GetHashFromBytes(byte[] bytes) { return new BigInteger(bytes).GetHashCode(); }


13
投票

GetHashCode()

 继承 
object
,但不会覆盖它。所以你得到的基本上就是 
object
 的实现。

如果您使用 .NET 6 或至少 .NET Core 2.1,您可以使用

7
投票
结构编写更少的代码并获得更好的性能。

使用 .NET 6 中提供的方法 HashCode.AddBytes()

public int GetHashCode(byte[] value) { var hash = new HashCode(); hash.AddBytes(value); return hash.ToHashCode(); }

使用 .NET Core 2.1 中提供的方法
HashCode.Add

public int GetHashCode(byte[] value) => value.Aggregate(new HashCode(), (hash, i) => { hash.Add(i); return hash; }).ToHashCode();

注意
HashCode.AddBytes()
的文档中说:

此方法不保证添加字节范围的结果与单独添加相同字节的结果相匹配。

在此

sharplab 演示
中,两者输出相同的结果,但这可能与 .NET 版本或运行时环境不同。

如果不是同一个实例,它将返回不同的哈希值。我猜它是基于它以某种方式存储的内存地址。

1
投票

© www.soinside.com 2019 - 2024. All rights reserved.