Vb6 为什么此函数生成的哈希代码不是唯一的?

Vb6 为什么此函数生成的哈希代码不是唯一的?,vb6,hash-code-uniqueness,hash-function,Vb6,Hash Code Uniqueness,Hash Function,我正在测试下面的VB函数,这是我从谷歌搜索中得到的。我计划使用它来生成哈希代码,以便进行快速字符串比较。但是,有时两个不同的字符串具有相同的哈希代码。例如,这些字符串 122Gen 1堆大小.NET CLR内存w3wp:mccsmtpteweb025.20833333E-02 122Gen 2堆大小.NET CLR内存w3wp:mccsmtpteweb015.20833333E-02 具有相同的哈希代码237117279 请告诉我: -这个函数有什么问题? -我怎样才能修好它 多谢各位 马丁 哈

我正在测试下面的VB函数,这是我从谷歌搜索中得到的。我计划使用它来生成哈希代码,以便进行快速字符串比较。但是,有时两个不同的字符串具有相同的哈希代码。例如,这些字符串

122Gen 1堆大小.NET CLR内存w3wp:mccsmtpteweb025.20833333E-02

122Gen 2堆大小.NET CLR内存w3wp:mccsmtpteweb015.20833333E-02

具有相同的哈希代码237117279

请告诉我: -这个函数有什么问题? -我怎样才能修好它

多谢各位

马丁


哈希函数不保证哈希值的唯一性。如果判断样本字符串的输入值范围大于输出值范围(例如32位整数),则实际上不可能实现唯一性。

哈希函数不保证哈希值的唯一性。如果判断样本字符串的输入值范围大于输出值范围(例如32位整数),则在物理上不可能实现唯一性。

这两个字符串具有相同的字符。请注意“2”和“1”是触发器

这就是散列值相同的原因


确保哈希函数考虑了字符的顺序。

两个字符串具有相同的字符。请注意“2”和“1”是触发器

这就是散列值相同的原因


确保哈希函数考虑了字符的顺序。

我不太了解您的工作环境。这是.Net代码吗?如果你真的想要好的散列码,我建议你研究加密散列算法,而不是尝试编写你自己的算法


顺便说一句,你能编辑你的帖子并将代码粘贴到工具栏中作为代码示例吗?这将使阅读更容易。

我不太了解您的工作环境。这是.Net代码吗?如果你真的想要好的散列码,我建议你研究加密散列算法,而不是尝试编写你自己的算法

顺便说一句,你能编辑你的帖子并将代码粘贴到工具栏中作为代码示例吗?这将使阅读更容易。

不要这样做

编写自己的哈希函数是一个很大的错误,因为您的语言肯定已经实现了SHA-1,这是一个非常好的哈希函数。如果您只需要32位而不是SHA-1提供的160位,只需使用SHA-1的最后32位

不要那样做


编写自己的哈希函数是一个很大的错误,因为您的语言肯定已经实现了SHA-1,这是一个非常好的哈希函数。如果您只需要32位而不是SHA-1提供的160位,只需使用SHA-1的最后32位

我敢打赌,两个字符串使用您的函数生成相同的哈希值的情况不止这些。事实上,它发生的频率可能比你想象的要高

需要了解的几件事:

首先,将出现哈希冲突。这是常有的事。即使使用非常非常大的空间,如MD5 128位,仍然有两个字符串可以生成相同的结果哈希。您必须通过创建bucket来处理这些冲突

第二,长整数实际上不是一个大的散列空间。如果你使用更多的比特,你将会得到更多的碰撞


第三,在Visual Basic中有一些库可以使用,比如.NET的System.Security.Cryptography命名空间,它们在散列方面比大多数普通人做得好得多。

我敢打赌,两个字符串使用函数生成同一散列的情况不止这些。事实上,它发生的频率可能比你想象的要高

需要了解的几件事:

首先,将出现哈希冲突。这是常有的事。即使使用非常非常大的空间,如MD5 128位,仍然有两个字符串可以生成相同的结果哈希。您必须通过创建bucket来处理这些冲突

第二,长整数实际上不是一个大的散列空间。如果你使用更多的比特,你将会得到更多的碰撞


第三,在Visual Basic中有一些库,如.NET的System.Security.Cryptography命名空间,这些库在哈希方面比大多数普通的库做得好得多。

没有任何哈希函数可以保证唯一性。有大约40亿个32位整数,因此,即使是最好的哈希函数,在出现大约40亿和1个字符串时也会生成重复项,而且很可能是很久以前的重复项

移动到64位哈希甚至128位哈希并不是真正的解决方案,尽管它降低了冲突的概率


如果您想要一个更好的散列函数,您可以查看加密散列,但最好重新考虑您的算法,并决定是否可以以其他方式处理冲突

任何哈希函数都不能保证唯一性。有大约40亿个32位整数,因此即使是最好的散列f 当使用大约40亿和1个字符串呈现时,unction将生成重复项,而且很可能是很久以前的重复项

移动到64位哈希甚至128位哈希并不是真正的解决方案,尽管它降低了冲突的概率

如果您想要一个更好的散列函数,您可以查看加密散列,但最好重新考虑您的算法,并决定是否可以以其他方式处理冲突

名称空间包含多个类,这些类可以为您进行哈希运算,例如,这些类可能会比您自己更好地对它们进行哈希运算,并且所需的工作量要少得多

您不必总是重新发明轮子。

名称空间包含多个类,这些类可以为您进行哈希运算,这样可能会比您自己更好地对它们进行哈希运算,而且所需的工作量要少得多


您不必总是重新发明轮子。

简单异或是一个糟糕的散列:您会发现许多字符串发生冲突。首先,散列不依赖于字符串中字母的顺序

尝试使用FNV散列


这真的很容易实现。它会在每次异或后移动散列码,因此相同的字母以不同的顺序将产生不同的散列。

简单异或是一个糟糕的散列:你会发现许多字符串发生冲突。首先,散列不依赖于字符串中字母的顺序

尝试使用FNV散列


这真的很容易实现。它在每个XOR之后移动哈希代码,因此相同的字母以不同的顺序将产生不同的哈希。

这里有一个MD5哈希的visual basic实现


这里有一个MD5哈希的VisualBasic实现


我为他修改了语法

此外,对于那些不确定环境或建议使用更安全的哈希的人来说:这是典型的.Net之前的VB,因为.Net需要括号来调用CopyMemory


IIRC,经典VB没有内置任何安全哈希。网络上也没有太多东西,所以这可能是他最好的选择。

我为他修复了语法高亮显示

此外,对于那些不确定环境或建议使用更安全的哈希的人来说:这是典型的.Net之前的VB,因为.Net需要括号来调用CopyMemory


IIRC,经典VB没有内置任何安全哈希。网络上也没有太多内容,所以这可能是他最好的选择。

这个特定的哈希函数对字符串中的所有字符进行异或运算。不幸的是,XOR是关联的:

(a XOR b) XOR c = a XOR (b XOR c)
因此,任何具有相同输入字符的字符串都将产生相同的哈希代码。除了两个字符的位置外,提供的两个字符串是相同的,因此它们应该具有相同的哈希代码


您可能需要找到更好的算法,MD5将是一个不错的选择。

这个特定的哈希函数对字符串中的所有字符进行异或运算。不幸的是,XOR是关联的:

(a XOR b) XOR c = a XOR (b XOR c)
因此,任何具有相同输入字符的字符串都将产生相同的哈希代码。除了两个字符的位置外,提供的两个字符串是相同的,因此它们应该具有相同的哈希代码


您可能需要找到更好的算法,MD5将是一个不错的选择。

异或运算是可交换的;也就是说,当对字符串中的所有字符进行异或运算时,字符的顺序并不重要。字符串的所有字谜都将产生相同的XOR哈希

在您的示例中,第二个字符串可以从第一个字符串生成,方法是将…Gen之后的1替换为后面的前2

你的功能没有问题。所有有用的哈希函数有时都会产生冲突,您的程序必须准备好解决冲突

当一个输入散列到一个已经用以前的输入标识的值时,会发生冲突。如果哈希算法无法生成冲突,则哈希值需要与输入值一样大。与仅存储输入值相比,这种散列算法的用途有限


-异或运算是可交换的;也就是说,当对字符串中的所有字符进行异或运算时,字符的顺序并不重要。字符串的所有字谜都将产生相同的XOR哈希

在您的示例中,第二个字符串可以从第一个字符串生成,方法是将…Gen之后的1替换为后面的前2

你的功能没有问题。所有有用的哈希函数有时都会产生冲突,您的程序必须准备好解决冲突

当一个输入散列到一个已经用以前的输入标识的值时,会发生冲突。如果哈希算法无法生成冲突,则哈希值需要与输入值一样大。与仅存储输入值相比,这种散列算法的用途有限


-如果最大的问题是它不符合 对于字节的位置,可以如下所示进行修复:

Private Function HashCode(Key As String) As Long
  On Error GoTo ErrorGoTo

  Dim lastEl As Long, i As Long
  ' copy ansi codes into an array of long'
  lastEl = (Len(Key) - 1) \ 4
  ReDim codes(lastEl) As Long
  ' this also converts from Unicode to ANSI'
  CopyMemory codes(0), ByVal Key, Len(Key)
  ' XOR the ANSI codes of all characters'

  For i = 0 To lastEl - 1
    HashCode = HashCode Xor (codes(i) + i) 'Xor'
  Next

ErrorGoTo:
  Exit Function
End Function

唯一的区别是,它将字符位置添加到XOR之前的字节值中。

如果最大的问题是它没有考虑字节的位置,您可以这样修复它:

Private Function HashCode(Key As String) As Long
  On Error GoTo ErrorGoTo

  Dim lastEl As Long, i As Long
  ' copy ansi codes into an array of long'
  lastEl = (Len(Key) - 1) \ 4
  ReDim codes(lastEl) As Long
  ' this also converts from Unicode to ANSI'
  CopyMemory codes(0), ByVal Key, Len(Key)
  ' XOR the ANSI codes of all characters'

  For i = 0 To lastEl - 1
    HashCode = HashCode Xor (codes(i) + i) 'Xor'
  Next

ErrorGoTo:
  Exit Function
End Function

唯一的区别是,它将字符位置添加到XOR之前的字节值中。

哈希函数并不意味着为不同的字符串返回不同的值。但是,一个好的散列函数应该为相似的字符串返回不同的值。哈希函数用于搜索有很多原因,包括搜索大型集合。如果哈希函数是好的,并且如果它返回范围[0,N-1]中的值,那么M个对象的大型集合将被划分为N个集合,每个集合大约有M/N个元素。这样,您只需要在M/N元素数组中搜索,而不需要在M元素数组中搜索

但是,如果只有2个字符串,那么计算这些字符串的哈希值就不会更快!最好只是比较这两个字符串

中断哈希函数可以是:



    unsigned int hash(const char* name) {
      unsigned mul=1;
      unsigned val=0;
      while(name[0]!=0) {
        val+=mul*((unsigned)name[0]);
        mul*=7; //you could use an arbitrary prime number, but test the hash dispersion afterwards
        name++;
      }
      return val;
    }


哈希函数并不意味着为不同的字符串返回不同的值。但是,一个好的散列函数应该为相似的字符串返回不同的值。哈希函数用于搜索有很多原因,包括搜索大型集合。如果哈希函数是好的,并且如果它返回范围[0,N-1]中的值,那么M个对象的大型集合将被划分为N个集合,每个集合大约有M/N个元素。这样,您只需要在M/N元素数组中搜索,而不需要在M元素数组中搜索

但是,如果只有2个字符串,那么计算这些字符串的哈希值就不会更快!最好只是比较这两个字符串

中断哈希函数可以是:



    unsigned int hash(const char* name) {
      unsigned mul=1;
      unsigned val=0;
      while(name[0]!=0) {
        val+=mul*((unsigned)name[0]);
        mul*=7; //you could use an arbitrary prime number, but test the hash dispersion afterwards
        name++;
      }
      return val;
    }


这是经典的VB。Net不允许使用CopyMemory语法。这是经典的VB。Net不允许使用CopyMemory语法。对于其他完全不同的字符串,例如15执行时间SM_RT数据访问sql_sr_usertitle_get_all:mccsmtpteweb011.4930555555556e-021和83执行时间SM_RT数据访问sql_so_pendingactvitem_添加_for Referral:mccsmtpteweb013.85416666666667E-021问题也仍然存在对于其他完全不同的字符串,如15执行时间SM_RT数据访问sql_sr_usertitle_get_all:mccsmtpteweb011.49305555556E-021和83执行时间SM_RT数据访问sql_so pendingactvitem添加_供参考:mccsmtpteweb013.854166666667E-021是的,它不是.NET。我正在尝试VBA for Excel中的函数。哦,好的,你应该编辑这个问题,说它是VBA,因为它不是.NET并不明显,大多数人都会认为它是。是的,它不是.NET。我正在尝试VBA for Excel中的函数。哦,好的,你应该编辑这个问题,说它是VBA,因为它不是.NET并不明显,大多数人都会认为它是。是的,你是对的。我对200K字符串测试了这个函数,有超过4K的冲突。什么是一个桶不寻找一个大的答案。。。我可以用谷歌搜索的东西是的,你是对的。我对200K字符串测试了这个函数,有超过4K的冲突。什么是一个桶不寻找一个大的答案。。。我可以在谷歌上搜索,所以创建自己的哈希函数是没有问题的,如果它用于字符串比较,你可能会比加密哈希快一点。创建自己的哈希函数没有问题,如果它用于字符串比较,您可能需要比加密散列快一点的东西。