String.GetHashCode 是怎样能够保证唯一的呢?

时间:2022-08-01 16:48:18
字符串的长度不限,组合不计其数,String.GetHashCode怎样保证它的唯一性呢?谁知道啊?

32 个解决方案

#1


up

#2


http://msdn2.microsoft.com/en-us/library/system.string.gethashcode.aspx#

#3


我试了一下,在.net framework 1.0和2.0下两个字串的hashcode不同,但是相同的framework我把程序考到哪台机子上都是一样的,我现在的主要疑问是:我就在同一台电脑,同一个程序中,无论我输入任意的字串,.net怎样保证hashcode唯一呢?Int32类型的值必定有限啊

#4


Int32=2^32=4G=32位Windows所能操作的最大内存

Int32类型的值必定是有限的,但是你的内存不是无限的......

#5


内存有限也只能限定一个字串的hashcode值,但是字串的组合是无限的啊

#6


也许你没明白我的意思,理论上字符串的组合是无限的,但是HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的,所以Int32对目前的32位系统来说是足够了的。

#7


能用的字符有限,字符串长度有限,字符串的组合怎么会是无限的

#8


况且Hash算法并不保证绝对的唯一

#9


.net Object.GetHashCode 方法的帮助中不是说“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”吗?

#10


字符串的组合不会无限吗?那Guid又怎么可以保证唯一呢?

#11


GUID也没有说能保证理论上的唯一,只不过重复的可能性在绝大多数的情况下都可以忽略不计。

因为GUID是个随机数,所以并不绝对保证唯一性,但发生标识符相重的可能性非成小。从理论上江,如果一台机器每秒产生10 000 000个GUID,则可以保证(概率意义上)3240年不重复。

       128位GUID是个随机数,其随机性由两方面的特性保证:一方面是空间,对于网络中的计算机通常取网络适配器的地址值,没有网络适配器的机器用其他随机数生成算法产生(具体什么算法呢?);另一方面是时间值,同一机器在不同时候产生的标识符总不相同。
(摘自COM原理与应用  潘爱民著)

#12


why don't you just create your own hash code generator method

#13


其实我的意思也很简单,我们把全球60亿人的DNA组成一个字符串,然后我要取得这些字串的HashCode存入数据库中,Int32只有40多亿,那另外的10几亿怎么保证?而且用什么方法保证所能够取得的HashCode唯一  “String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”

#14


如果是你说的这种情况,那还是建议使用GDUI了。

#15


呵呵,其实我就是想既然说“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”
那他又怎么可以保证唯一呢?

#16


唉,前面不是说了么,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”。

#17


1.0和2.0的hash算法不一样,所以返回的值就不一样了

#18


HashCode 并不能保证唯一,只是保证所有HashCode能够均匀分布在int的值域中

#19


那句话“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”不知道是不是说只要字符串值不同哈希代码就不同呢?
如果我的应用系统中有超过4,294,967,296条字符串,那是不是就没法满足了?

#20


GetHashCode 的默认实现不保证唯一性或一致性,因此,不能在进行散列时用作唯一对象标识符。

String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。另外,该方法使用字符串中的所有字符生成相当随机的分布式输出,即使当输入集中在某些范围内时(例如,许多用户可能有只包含低位 128 个 ASCII 字符的字符串,即使字符串可以包含 65,535 个 Unicode 字符中的任何字符)。



http://www.dbo.cn/Resource/msdn/cpref/frlrfsystemobjectclassgethashcodetopic.htm

#21


From MSDN:
String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。

即使你的系统中有4,294,967,296条字符串,但是你不可能同时把这么多字符串同时加载到内存中,所以HashCode还是适用的,这也就是我一直说的,,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”,这里的应用指的是在运行当中的程序。
不知道我这么说 wql425(wql) 明白我的意思没有?

#22


String 的 HashCode并不是唯一的

可能存在两个不同的String,他们的HashCode是一样的,很容易找到这个例子

也就是说 存在  s1 s2 , s1 != s2

但是 s1.GetHashCode() == s2.GetHashCode()

#23


to s5689412(华君)

你说的 From MSDN:

是哪里的MSDN? 拜托不要诬陷 MS 好不好!

#24


"String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码"

人家MSDN说的意思是,如果一个字符串是确定的,那么它的HashCode也确定

而不会改变(相同的.NET 版本情况下),但是并没有说

如果字符串不同,他们的 HashCode也不同啊,就算是当前运行的同一个进程

也可能存在 HashCode 相同,但是字符串不同的情况的!

#25


看来GetHashCode肯定不会唯一了,不过也奇怪,取了50M左右的不同字串进行比对,没有发现相同,哈哈,不知道是不是我比较幸运,由于比对太慢了,没有继续了,不过我确实想找出两个字符串,它们的值不同但HashCode相同,真不好找啊,而且对于同一个字串昨天、今天、不同的电脑上的HashCode一直一样,这也让我没有办法确定hashcode的不唯一啊

#26


to wql425(wql)

算算下面几个"字符串" 的HashCode  :)

using System;
public class test
{
  static void Main()
  {
         // .net 1.1
   Console.WriteLine("0.883744205759719".GetHashCode());
   Console.WriteLine("0.125208284298521".GetHashCode());

         // .net 2.0
   Console.WriteLine("0.89265452879139".GetHashCode());
   Console.WriteLine("0.280527401380486".GetHashCode());
  }
}

#27


Visual Studio .NET 2003 自带的MSDN。

那句话上面的内容如下(摘到我上面提到的那句话为止):

Object.GetHashCode 方法  [C#]请参见
Object 类 | Object 成员 | System 命名空间 | 哈希表集合类型 | Hashtable | Object 成员(Visual J# 语法) | C++ 托管扩展编程 
要求
平台: Windows 98, Windows NT 4.0, Windows ME, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 系列, .NET Framework 精简版 - Windows CE .NET, 公共语言基础结构 (CLI) 标准
语言
C#

C++

JScript

Visual Basic

全部显示
用作特定类型的哈希函数,适合在哈希算法和数据结构(如哈希表)中使用。

[Visual Basic]
Public Overridable Function GetHashCode() As Integer

[C#]
public virtual int GetHashCode();

[C++]
public: virtual int GetHashCode();

[JScript]
public function GetHashCode() : int;

返回值
当前 Object 的哈希代码。

备注
此方法可由派生类重写。值类必须重写此方法,以提供适合该类并且确保哈希表中有更好的分布的哈希函数。在哈希表中可以用作键的类也必须重写此方法,因为在哈希表中用作键的对象对于通过此方法生成类自己的哈希代码是必需的。但是,在构造 Hashtable 时,如果用作键的对象没有提供有用的 GetHashCode 实现,您可以提供另外一个基于 System.Collections.IHashCodeProvider 接口的哈希代码提供程序。

GetHashCode 的默认实现不保证唯一性或一致性,因此,不能在进行散列时用作唯一对象标识符。派生类必须用返回唯一哈希代码的实现重写 GetHashCode。为了获得最佳结果,哈希代码必须基于实例字段或属性(而非静态字段或属性)的值。

对实施者的说明:  

哈希函数用于快速生成一个与对象的值相对应的数字(哈希代码)。哈希函数通常是特定于每个 Type 的,而且,必须至少使用一个实例字段作为输入。

哈希函数必须具有下列属性: 

如果两个类型相同的对象表示相同的值,则哈希函数必须为两个对象返回相同的常数值。 
为了获得最佳性能,哈希函数必须为所有输入生成随机分布。 
不论对该对象进行什么样的更改,哈希函数都必须返回完全相同的值。 
例如,String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。另外,该方法使用字符串中的所有字符生成相当随机的分布式输出,即使当输入集中在某些范围内时(例如,许多用户可能有只包含低位 128 个 ASCII 字符的字符串,即使字符串可以包含 65,535 个 Unicode 字符中的任何字符)。

#28


to  tiaoci(我挑刺,我快乐) :
哈哈,我要的就是这个结果,不知道你怎么找到那两个字串的呢?

#29


to 华君, 我想你理解错了,至少不能得出这个结论

"这也就是我一直说的,,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”,这里的应用指的是在运行当中的程序。"

是吧,我那个例子已经说明问题了

#30


to wql425(wql) , 我眼睛一瞄就瞄出来了啊,哈

其实就是用随机数生成字符串,放到Hashtable中

直到发现重复的HashCode

#31


哈哈,谢谢啦,大家准备接分吧

#32


是的,我承认在这一点上我的理解上是有问题的,在看你给出的那两个字符串之后,
的确是相同的hashcode,
不过在此之前,没有事实说话的情况下,我只能以MSDN上的为准,是吧?

#1


up

#2


http://msdn2.microsoft.com/en-us/library/system.string.gethashcode.aspx#

#3


我试了一下,在.net framework 1.0和2.0下两个字串的hashcode不同,但是相同的framework我把程序考到哪台机子上都是一样的,我现在的主要疑问是:我就在同一台电脑,同一个程序中,无论我输入任意的字串,.net怎样保证hashcode唯一呢?Int32类型的值必定有限啊

#4


Int32=2^32=4G=32位Windows所能操作的最大内存

Int32类型的值必定是有限的,但是你的内存不是无限的......

#5


内存有限也只能限定一个字串的hashcode值,但是字串的组合是无限的啊

#6


也许你没明白我的意思,理论上字符串的组合是无限的,但是HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的,所以Int32对目前的32位系统来说是足够了的。

#7


能用的字符有限,字符串长度有限,字符串的组合怎么会是无限的

#8


况且Hash算法并不保证绝对的唯一

#9


.net Object.GetHashCode 方法的帮助中不是说“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”吗?

#10


字符串的组合不会无限吗?那Guid又怎么可以保证唯一呢?

#11


GUID也没有说能保证理论上的唯一,只不过重复的可能性在绝大多数的情况下都可以忽略不计。

因为GUID是个随机数,所以并不绝对保证唯一性,但发生标识符相重的可能性非成小。从理论上江,如果一台机器每秒产生10 000 000个GUID,则可以保证(概率意义上)3240年不重复。

       128位GUID是个随机数,其随机性由两方面的特性保证:一方面是空间,对于网络中的计算机通常取网络适配器的地址值,没有网络适配器的机器用其他随机数生成算法产生(具体什么算法呢?);另一方面是时间值,同一机器在不同时候产生的标识符总不相同。
(摘自COM原理与应用  潘爱民著)

#12


why don't you just create your own hash code generator method

#13


其实我的意思也很简单,我们把全球60亿人的DNA组成一个字符串,然后我要取得这些字串的HashCode存入数据库中,Int32只有40多亿,那另外的10几亿怎么保证?而且用什么方法保证所能够取得的HashCode唯一  “String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”

#14


如果是你说的这种情况,那还是建议使用GDUI了。

#15


呵呵,其实我就是想既然说“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”
那他又怎么可以保证唯一呢?

#16


唉,前面不是说了么,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”。

#17


1.0和2.0的hash算法不一样,所以返回的值就不一样了

#18


HashCode 并不能保证唯一,只是保证所有HashCode能够均匀分布在int的值域中

#19


那句话“String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。”不知道是不是说只要字符串值不同哈希代码就不同呢?
如果我的应用系统中有超过4,294,967,296条字符串,那是不是就没法满足了?

#20


GetHashCode 的默认实现不保证唯一性或一致性,因此,不能在进行散列时用作唯一对象标识符。

String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。另外,该方法使用字符串中的所有字符生成相当随机的分布式输出,即使当输入集中在某些范围内时(例如,许多用户可能有只包含低位 128 个 ASCII 字符的字符串,即使字符串可以包含 65,535 个 Unicode 字符中的任何字符)。



http://www.dbo.cn/Resource/msdn/cpref/frlrfsystemobjectclassgethashcodetopic.htm

#21


From MSDN:
String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。

即使你的系统中有4,294,967,296条字符串,但是你不可能同时把这么多字符串同时加载到内存中,所以HashCode还是适用的,这也就是我一直说的,,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”,这里的应用指的是在运行当中的程序。
不知道我这么说 wql425(wql) 明白我的意思没有?

#22


String 的 HashCode并不是唯一的

可能存在两个不同的String,他们的HashCode是一样的,很容易找到这个例子

也就是说 存在  s1 s2 , s1 != s2

但是 s1.GetHashCode() == s2.GetHashCode()

#23


to s5689412(华君)

你说的 From MSDN:

是哪里的MSDN? 拜托不要诬陷 MS 好不好!

#24


"String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码"

人家MSDN说的意思是,如果一个字符串是确定的,那么它的HashCode也确定

而不会改变(相同的.NET 版本情况下),但是并没有说

如果字符串不同,他们的 HashCode也不同啊,就算是当前运行的同一个进程

也可能存在 HashCode 相同,但是字符串不同的情况的!

#25


看来GetHashCode肯定不会唯一了,不过也奇怪,取了50M左右的不同字串进行比对,没有发现相同,哈哈,不知道是不是我比较幸运,由于比对太慢了,没有继续了,不过我确实想找出两个字符串,它们的值不同但HashCode相同,真不好找啊,而且对于同一个字串昨天、今天、不同的电脑上的HashCode一直一样,这也让我没有办法确定hashcode的不唯一啊

#26


to wql425(wql)

算算下面几个"字符串" 的HashCode  :)

using System;
public class test
{
  static void Main()
  {
         // .net 1.1
   Console.WriteLine("0.883744205759719".GetHashCode());
   Console.WriteLine("0.125208284298521".GetHashCode());

         // .net 2.0
   Console.WriteLine("0.89265452879139".GetHashCode());
   Console.WriteLine("0.280527401380486".GetHashCode());
  }
}

#27


Visual Studio .NET 2003 自带的MSDN。

那句话上面的内容如下(摘到我上面提到的那句话为止):

Object.GetHashCode 方法  [C#]请参见
Object 类 | Object 成员 | System 命名空间 | 哈希表集合类型 | Hashtable | Object 成员(Visual J# 语法) | C++ 托管扩展编程 
要求
平台: Windows 98, Windows NT 4.0, Windows ME, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 系列, .NET Framework 精简版 - Windows CE .NET, 公共语言基础结构 (CLI) 标准
语言
C#

C++

JScript

Visual Basic

全部显示
用作特定类型的哈希函数,适合在哈希算法和数据结构(如哈希表)中使用。

[Visual Basic]
Public Overridable Function GetHashCode() As Integer

[C#]
public virtual int GetHashCode();

[C++]
public: virtual int GetHashCode();

[JScript]
public function GetHashCode() : int;

返回值
当前 Object 的哈希代码。

备注
此方法可由派生类重写。值类必须重写此方法,以提供适合该类并且确保哈希表中有更好的分布的哈希函数。在哈希表中可以用作键的类也必须重写此方法,因为在哈希表中用作键的对象对于通过此方法生成类自己的哈希代码是必需的。但是,在构造 Hashtable 时,如果用作键的对象没有提供有用的 GetHashCode 实现,您可以提供另外一个基于 System.Collections.IHashCodeProvider 接口的哈希代码提供程序。

GetHashCode 的默认实现不保证唯一性或一致性,因此,不能在进行散列时用作唯一对象标识符。派生类必须用返回唯一哈希代码的实现重写 GetHashCode。为了获得最佳结果,哈希代码必须基于实例字段或属性(而非静态字段或属性)的值。

对实施者的说明:  

哈希函数用于快速生成一个与对象的值相对应的数字(哈希代码)。哈希函数通常是特定于每个 Type 的,而且,必须至少使用一个实例字段作为输入。

哈希函数必须具有下列属性: 

如果两个类型相同的对象表示相同的值,则哈希函数必须为两个对象返回相同的常数值。 
为了获得最佳性能,哈希函数必须为所有输入生成随机分布。 
不论对该对象进行什么样的更改,哈希函数都必须返回完全相同的值。 
例如,String 类提供的 GetHashCode 实现为唯一的字符串值返回唯一的哈希代码。因此,如果两个 String 对象表示相同的字符串值,则它们返回相同的哈希代码。另外,该方法使用字符串中的所有字符生成相当随机的分布式输出,即使当输入集中在某些范围内时(例如,许多用户可能有只包含低位 128 个 ASCII 字符的字符串,即使字符串可以包含 65,535 个 Unicode 字符中的任何字符)。

#28


to  tiaoci(我挑刺,我快乐) :
哈哈,我要的就是这个结果,不知道你怎么找到那两个字串的呢?

#29


to 华君, 我想你理解错了,至少不能得出这个结论

"这也就是我一直说的,,“HashCode并不是要保证所有字符串的唯一性,它只是保证在当前系统的应用上是唯一的”,这里的应用指的是在运行当中的程序。"

是吧,我那个例子已经说明问题了

#30


to wql425(wql) , 我眼睛一瞄就瞄出来了啊,哈

其实就是用随机数生成字符串,放到Hashtable中

直到发现重复的HashCode

#31


哈哈,谢谢啦,大家准备接分吧

#32


是的,我承认在这一点上我的理解上是有问题的,在看你给出的那两个字符串之后,
的确是相同的hashcode,
不过在此之前,没有事实说话的情况下,我只能以MSDN上的为准,是吧?