Hash 如何处理哈希冲突?

Hash 如何处理哈希冲突?,hash,guid,identifier,hash-collision,robustness,Hash,Guid,Identifier,Hash Collision,Robustness,我正在开发一个游戏,其中游戏世界中的每一件事情都由一个全局唯一标识符表示 这些ID每个测量64位,通过将创建时间、机器网络地址和随机数散列在一起生成。根据维基百科上的文章,对于2亿条记录,哈希冲突的概率为0.1% 因为我不太可能得到这么多的记录,所以我们可以认为没有杂凑会发生冲突。但我不希望出现这种情况,而是让我的应用程序处理罕见的id冲突,从而导致哈希冲突 否则,该行为将是非常不受欢迎的,因为游戏世界中两个独立的事物将有一个连接,从而共享它们的属性,如位置、运动、健康点等 如何处理哈希冲突?通

我正在开发一个游戏,其中游戏世界中的每一件事情都由一个全局唯一标识符表示

这些ID每个测量64位,通过将创建时间、机器网络地址和随机数散列在一起生成。根据维基百科上的文章,对于2亿条记录,哈希冲突的概率为0.1%

因为我不太可能得到这么多的记录,所以我们可以认为没有杂凑会发生冲突。但我不希望出现这种情况,而是让我的应用程序处理罕见的id冲突,从而导致哈希冲突

否则,该行为将是非常不受欢迎的,因为游戏世界中两个独立的事物将有一个连接,从而共享它们的属性,如位置、运动、健康点等


如何处理哈希冲突?通常如何处理它们?

哈希冲突通常通过两种方式处理:

  • 使用更大的散列,这样冲突实际上是不可能的

  • 将哈希代码视为非唯一的,并对实际数据使用相等比较器来确定唯一性


  • 128位GUID使用第一种方法。NET中的
    HashSet
    类就是第二种方法的一个例子。

    事实上,人们通常认为GUID不会发生冲突。听起来你想要的不是真正的哈希,而是唯一的标识符。是否有任何理由不使用128位GUID?@ BARA我想使用C++标准类型,如“代码>未签名的长It/Eng>”,而不是数组来存储ID。此外,我没有那么多的记录。但无论如何,问题仍然存在于任何id长度。@danijar然后我会回到“为什么使用散列?”的问题,你真正想要的是一个唯一的id,除非有理由不这样做(假设id是以分布式方式生成的)。@bara我需要id,对吗。但由于数据可以从不同的独立机器(savegame、修改、补丁、插件)加载,因此该id必须是全局唯一的。我猜这是一种散列,对吧?如果128位GUID发生冲突怎么办?@danijar:对于26亿条记录,发生冲突的概率是0.0000000000000000001%。这与GUID在内存电路中自动改变的概率大致相同,我仍然不能使用128位。这有多种原因。例如,像
    std::unordered_map
    这样的stl容器只接受64位的
    std::size_t
    散列。使用较大的ID需要对较小的映射哈希再次进行哈希,这是无用的,因为这是主要用例。能否请您详细说明如何
    将哈希代码视为非唯一的
    ?@danijar:第二种选择只是接受可能存在哈希冲突。对于散列实际发生冲突的罕见情况,您只需比较实际数据,看看它是否是相同的值。好的,然后我必须扫描加载的数据,并将对冲突散列的所有引用更新为新生成的引用。可能实际的问题是关于这个过程,但我认为这是如此依赖于实现,以至于它将过于本地化。