Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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
String BobJenkinsHash函数的结果是否为负?_String_Delphi_Hash - Fatal编程技术网

String BobJenkinsHash函数的结果是否为负?

String BobJenkinsHash函数的结果是否为负?,string,delphi,hash,String,Delphi,Hash,环境:Win7 64位,Delphi 2010,Win32项目 我试图通过Generics.Defaults中的BobJenkinsHash()函数获取字符串集的整数散列值 这是可行的,但有些问题我不清楚 函数的结果会是负的吗 在我看来 它被用作hashword()函数的结果类型: uint32_t hashword( const uint32_t *k, /* the key, an array of uint32_t values */ size_t

环境:Win7 64位,Delphi 2010,Win32项目

我试图通过Generics.Defaults中的BobJenkinsHash()函数获取字符串集的整数散列值

这是可行的,但有些问题我不清楚

  • 函数的结果会是负的吗 在我看来 它被用作hashword()函数的结果类型:

    uint32_t hashword(
    const uint32_t *k,                   /* the key, an array of uint32_t values  */
    size_t          length,               /* the length of the key, in uint32_ts    */
    uint32_t        initval)         /* the previous hash, or an arbitrary value */
    {
    
    是无符号整数吗

  • 第二个问题是,对于具有相同值的不同字符串,我有不同的结果:

    'DEFPROD001' => 759009858
    'DEFPROD001' => 1185633302
    
  • 这是正常的行为吗

    计算散列的完整函数(如果第一个参数为空,则返回第二个):


    Delphi实现声明如下:

    function BobJenkinsHash(const Data; Len, InitData: Integer): Integer;
    
    它返回一个有符号的32位整数。是的,这个实现可以返回负值

    您提到的C实现返回一个无符号32位整数。这样就不能返回负值

    假设两种实现都正确,那么在给定相同输入的情况下,它们将返回相同的32位输出。只是当解释为有符号或无符号值时,这些位有不同的含义

    至于第二个问题,将相同的字符串传递给哈希函数将产生相同的哈希。您一定是在测试用例中出错了

    BobJenkinsHash(defaultID, Length(defaultID) * SizeOf(defaultID), 0);
    
    这里的
    defaultID
    是一个
    string
    变量,它被实现为一个指针。因此,您正在对地址进行哈希运算。由于你的长度参数不正确,你甚至不能正确地做这件事。相反,你需要写:

    BobJenkinsHash(Pointer(defaultID)^, Length(defaultID) * SizeOf(Char), 0);
    
    该程序演示了:

    {$APPTYPE CONSOLE}
    
    uses
      System.Generics.Defaults;
    
    var
      s, t: string;
    
    begin
      s := 'DEFPROD001';
      t := 'DEFPROD001';
    
      Writeln(BobJenkinsHash(s, Length(s) * SizeOf(s), 0));
      Writeln(BobJenkinsHash(t, Length(t) * SizeOf(t), 0));
    
      Writeln(BobJenkinsHash(Pointer(s)^, Length(s) * SizeOf(Char), 0));
      Writeln(BobJenkinsHash(Pointer(t)^, Length(t) * SizeOf(Char), 0));
    
      Readln;
    end.
    
    输出:

    2129045826 -331457644 -161666357 -161666357 2129045826 -331457644 -161666357 -161666357
    他可能对同一文本有不同的二进制表示:UTF8或UTF16@Arioch'编号
    字符串始终为UTF-16。“他正在对地址进行哈希运算(然后再进行一些运算)@David回答得很好,一如既往!谢谢。现在,相同的值具有相同的哈希。也许你知道如何在风险最小的情况下使回报值为正值?只是ABS()就足够了吗?:)或者MAXINT+hash表示负值…
    abs
    是一个非常糟糕的主意,因为它只使用32位中的31位,会使哈希函数的性能很差。此外,由于abs(MININT)超出范围,它将失败。只需将散列重新解释为
    基数
    。对于
    Cardinal(inthash)
    这看起来是错误的:
    Length(defaultID)*SizeOf(defaultID)
    。我会使用类似
    Length(defaultID)*SizeOf(char)
    2129045826 -331457644 -161666357 -161666357