C# 如何生成唯一的哈希代码?

C# 如何生成唯一的哈希代码?,c#,hashcode,C#,Hashcode,所以,我有这个结构。它覆盖了一些函数和运算符,但这并不重要 public struct Vector3 { public float X, Y, Z; } 我通过一个哈希表过滤这些数据集,效果很好。但我想验证是否只删除了重复项。默认情况下,IDE为GetHashCode()方法提供了以下代码: 我觉得很可疑。我非常确信,单是这些因素就会在INT_32上产生溢出。此外,我感到困惑的是,所有三个浮动似乎具有相同的“重量”(-1521134295)。另外,我不确定浮点的GetHashCode

所以,我有这个结构。它覆盖了一些函数和运算符,但这并不重要

public struct Vector3
{
    public float X, Y, Z;
}
我通过一个哈希表过滤这些数据集,效果很好。但我想验证是否只删除了重复项。默认情况下,IDE为GetHashCode()方法提供了以下代码:

我觉得很可疑。我非常确信,单是这些因素就会在INT_32上产生溢出。此外,我感到困惑的是,所有三个浮动似乎具有相同的“重量”(-1521134295)。另外,我不确定浮点的GetHashCode()做什么。它的位模式本身应该已经是唯一的了

从96位的输入创建一个独特的32位模式是不可能的

那么它是如何工作的呢?

  • HashMap是否在使用 相同的哈希代码

  • 我只是幸运吗

  • 我的IDE生成的“权重”和 startvalue

PS:对于感兴趣的人,结构的代码在这里

public struct Vector3
{
    public float X, Y, Z;

    public Vector3(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }     

    public static bool operator ==(Vector3 a, Vector3 b)
    {
        return (a.X == b.X && a.Y == b.Y && a.Z == b.Z);
    }

    public static bool operator !=(Vector3 a, Vector3 b)
    {
        return (a.X != b.X || a.Y != b.Y || a.Z != b.Z);
    }

    public static Vector3 operator +(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
    }

    public static Vector3 operator -(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
    }

    public float Magnitued
    {
        get
        {
            return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
        }
        private set { }
    }

    public Vector3 Normalized
    {
        get
        {
            var mag = Magnitued;
            return new Vector3(X / mag, Y / mag, Z / mag);
        }

        private set { }
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Vector3))
        {
            return false;
        }

        var vector = (Vector3)obj;
        return X == vector.X && Y == vector.Y && Z == vector.Z;
    }

    public override int GetHashCode()
    {
        var hashCode = -307843816;
        hashCode = hashCode * -1521134295 + X.GetHashCode();
        hashCode = hashCode * -1521134295 + Y.GetHashCode();
        hashCode = hashCode * -1521134295 + Z.GetHashCode();
        return hashCode;
    }
}

我想你这里有个误会。散列码不应该是唯一的,因为正如您所观察到的,有时它是不可能的

主要要求是被认为“相等”的对象应该具有相同的哈希代码

只要满足要求,就可以导致溢出

这一点在附录中也有说明:

两个相等的对象返回相等的哈希代码。但是,情况并非如此:相等的哈希代码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的哈希代码


您还可以在链接页面中看到
GetHashCode
的其他实现。

请注意,由于哈希的大小有限,因此不希望哈希是唯一的。看见好的散列算法可以最小化典型输入数据的冲突
GetHashCode()
通常用于确定两个项目是否可能是同一个项目。需要进一步检查以确认这一点。溢出通常没有问题,您可以将代码包装在未选中的
部分中。无论如何,散列不是唯一的,所以两个不相等的数字可能有相同的散列码。但是,两个相等的数字必须具有相同的哈希代码。通常结构为equals和hashcodes提供了一个默认实现,这很好。它通过按位比较每个成员来实现,因此您的实现似乎是冗余的。有关更多详细信息,请参阅。
public struct Vector3
{
    public float X, Y, Z;

    public Vector3(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }     

    public static bool operator ==(Vector3 a, Vector3 b)
    {
        return (a.X == b.X && a.Y == b.Y && a.Z == b.Z);
    }

    public static bool operator !=(Vector3 a, Vector3 b)
    {
        return (a.X != b.X || a.Y != b.Y || a.Z != b.Z);
    }

    public static Vector3 operator +(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
    }

    public static Vector3 operator -(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
    }

    public float Magnitued
    {
        get
        {
            return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
        }
        private set { }
    }

    public Vector3 Normalized
    {
        get
        {
            var mag = Magnitued;
            return new Vector3(X / mag, Y / mag, Z / mag);
        }

        private set { }
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Vector3))
        {
            return false;
        }

        var vector = (Vector3)obj;
        return X == vector.X && Y == vector.Y && Z == vector.Z;
    }

    public override int GetHashCode()
    {
        var hashCode = -307843816;
        hashCode = hashCode * -1521134295 + X.GetHashCode();
        hashCode = hashCode * -1521134295 + Y.GetHashCode();
        hashCode = hashCode * -1521134295 + Z.GetHashCode();
        return hashCode;
    }
}