C#这个C哈希函数的等价物

时间:2015-05-07 20:14:01

标签: c# c

我遇到了这个C代码,它是一个哈希算法,可以为类似的字符串生成相同的哈希值:

unsigned long kaz_hash(const char *str)
{
    static unsigned long randbox[] = {
        0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
        0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
        0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
        0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
    };

    long acc = 0;

    while (*str) {
        acc ^= randbox[(*str + acc) & 0xf];
        acc = (acc << 1) | (acc >> 31);
        acc &= 0xffffffffU;
        acc ^= randbox[((*str++ >> 4) + acc) & 0xf];
        acc = (acc << 2) | (acc >> 30);
        acc &= 0xffffffffU;
    }
    return acc;
}

我试图在C#中使用它,这就是我提出的:

public static ulong kaz_hash(string str) {
  ulong[] randbox = {
    0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
    0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
    0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
    0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
  };

  long acc = 0;

  foreach (long c in str) {
    acc ^= (long)randbox[(c + acc) & 0xf];
    acc = (acc << 1) | (acc >> 31);
    acc &= 0xffffffffU;
    acc ^= (long)randbox[((c >> 4) + acc) & 0xf];
    acc = (acc << 2) | (acc >> 30);
    acc &= 0xffffffffU;
  }
  return (ulong)acc;
}

但是,有一些问题。这两个函数没有产生相同的结果。

修改

感谢所有评论和帮助。我终于能够做到这一点。以下是工作版本:

public static uint kaz_hash(string str) {
  uint[] randbox = {
    0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
    0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
    0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
    0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
  };

  int acc = 0;

  unchecked {
    foreach (int c in str) {
      acc ^= (int)randbox[(c + acc) & 0xf];
      acc = (acc << 1) | (acc >> 31);
      acc &= (int)0xffffffffU;
      acc ^= (int)randbox[((c >> 4) + acc) & 0xf];
      acc = (acc << 2) | (acc >> 30);
      acc &= (int)0xffffffffU;
    }
  }
  return (UInt32)acc;
}

1 个答案:

答案 0 :(得分:0)

我用“abc”,“abcd”和“abcde”尝试了下面的代码,C#代码返回与C ++代码相同的值:

    public static int kaz_hash(string str)
        {
            UInt32[] randbox = {
            0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
            0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
            0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
            0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
            };

            int acc = 0;

            foreach (UInt32 c in str)
            {                    
                acc ^= (int)randbox[(c + acc) & 0xf];                    
                acc = (acc << 1) | (acc >> 31);
                acc &= -1;
                acc ^= (int)randbox[((c >> 4) + acc) & 0xf];
                acc = (acc << 2) | (acc >> 30);
                acc &= -1;
            }
            return acc;
        }