Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Guid&;GetHashCode唯一性_C#_.net - Fatal编程技术网

C# Guid&;GetHashCode唯一性

C# Guid&;GetHashCode唯一性,c#,.net,C#,.net,给定以下键: int key = Guid.NewGuid().GetHashCode(); 此键是否与Guid的唯一性一样唯一?GetHashCode()返回一个整数-它不能与Guid一样唯一,因此没有-可能存在冲突,并且不保证唯一性 哈希代码的要点是它应该均匀地分布在整个哈希范围内,这样冲突通常应该很少发生,但您始终有可能发生冲突,并且必须适应这种情况。Guid是一个128位的数字。int是32位数字,因此它不能像Guid那样“唯一” 此外,GetHashCode返回。。。一个哈希代码,它

给定以下键:

int key = Guid.NewGuid().GetHashCode();
此键是否与Guid的唯一性一样唯一?

GetHashCode()
返回一个整数-它不能与
Guid
一样唯一,因此没有-可能存在冲突,并且不保证唯一性


哈希代码的要点是它应该均匀地分布在整个哈希范围内,这样冲突通常应该很少发生,但您始终有可能发生冲突,并且必须适应这种情况。

Guid是一个128位的数字。int是32位数字,因此它不能像Guid那样“唯一”

此外,GetHashCode返回。。。一个哈希代码,它并不意味着在任何方面都是唯一的。有关GetHashCode()存在的原因,请参见此处的其他讨论。

表示不存在。GUID有16个字节的信息—128位。
int
有32位信息。(编辑:为了澄清注释,据我所知,.NET GUID将允许任意设置这128位;随机生成的GUID遵循更严格的模式,因此不会随机生成2128个不同的值。不过仍然超过232个。)

有2128个可能的GUID和232个可能的哈希代码-因此每个GUID不可能有不同的哈希代码

但是,还有更多-
GetHashCode()
从来都不是用来表示唯一性的。如果可以的话,那就太好了——但它不必这样做,即使有足够的
int
值可以这样做

int.GetHashCode()
返回(比如)值除以二是完全有效的。。。所以-1、0和1都会得到一个0的散列码;3和4将得到一个2等的散列码。这不是很好(而且比只返回值要慢),但这将是一个有效的实现。它将满足
GetHashCode
的所有约束,即如果对两个相等的值调用它,它将返回相同的哈希代码


事实上,为所有值返回一个常量是一个有效的实现——尽管这是一个非常无用的实现,因为它将哈希表的正常快速查找转化为一个O(N)操作。

就在今天,我注意到了Guid.GetHashCode()的另一个问题:在Microsoft.NET实现中,不是每个“字节”对
Guid
进行哈希处理:有6个字节的
Guid
未进行哈希处理,因此对其中一个字节的任何更改都不会更改哈希代码

我们可以从以下几个方面看到:

对于像这样的
Guid
,生成的不同散列数非常少(256个不同的值),因为
3478ec9d
/
3478ec9e
不会被散列。

。我有一个类,其中两个
Guid
值用于区分不同的对象,我发现我遇到了大量的冲突(我的Guid不是随机生成的)。这是我用来解决这个问题的代码
Guid1
Guid2
是区分对象的
Guid
类型的属性。代码如下


还应注意的是,GUID不保证是唯一的。有传言说,2012年12月21日将生成重复的GUID。@HansPassant很抱歉让您失望。谣言是假的。@Joey:当然是随机生成的,但我不认为有什么能阻止你从一个16字节数组进入
Guid
构造函数,并使用你想要的任何值。你有任何相反的证据吗?@Joey:嗯,我们专门讨论的是.NET
Guid
类型,我仍然认为该类型有2^128个可能的值。@Joey:当然,通常情况下,您不会得到在Unicode中没有赋值的字符串,但它们仍然是可以轻松创建的值。如果两个不同的实例可以具有相同的值,那么
GetHashCode
有什么用呢?它不能可靠地用于确认两件事情是相同的,或者两件事情是不同的@杰兹:它可以用来确认两件事是不同的——如果它们有不同的散列码,它们就不可能相等(假设实现正确)。如果它们具有相同的哈希代码,则它们可能相等。关键是,如果你在一个地图中有一百万个键,并且你试图找到其中一个,你可以非常迅速地将其缩小到“只有具有正确哈希代码的键”,然后你可以对所有候选键调用Equals,以找出哪个键实际上是正确的。哇,非常有趣的观察结果。不确定MS为什么不散列整个GUID,但这是需要注意的……对于版本1 UUID,
GetHashCode()
中包含的字段是60位时间戳和MAC地址的一部分。对于版本4 UUID(从
Guid.NewGuid()
)获得),几乎所有Guid字节都是随机的。所以在这些情况下,算法似乎还可以。我在OracleDB上生成GUI的生产中遇到了这个问题。有人能解释为什么它不散列所有的值吗?我很难相信散列额外的6个字节会是一个性能问题?@PhilippAumayr在.NET Core中已被更改。。。现在,所有BIT均已完成(参见)从2016年开始:
return _a ^ (((int)_b << 16) | (int)(ushort)_c) ^ (((int)_f << 24) | _k);
c482fbe1-9f16-4ae9-a05c-383478ec9d13
c482fbe1-9f16-4ae9-a05c-383478ec9d14
c482fbe1-9f16-4ae9-a05c-383478ec9d15
...
c482fbe1-9f16-4ae9-a05c-383478ec9dff
c482fbe1-9f16-4ae9-a05c-383478ec9e00
c482fbe1-9f16-4ae9-a05c-383478ec9e01
    public override int GetHashCode()
    {
        int hash = 173;
        foreach (Byte b in Guid1.ToByteArray().Concat(Guid2.ToByteArray()))
        {
            hash = hash * 983 + b;
        }
        return hash;
    }