简体   繁体   English

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

[英]C# Equivalent of this C hash function

I came across this C code which is a hashing algorithm to produce same hash for similar strings: 我遇到了这个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;
}

I am trying to use this in C#, this is what I came up with: 我想在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;
}

However, there is something wrong. 但是,有一些问题。 The 2 functions aren't producing the same results. 这2个函数没有产生相同的结果。

Edit 编辑

Thanks to all comments and help. 感谢所有评论和帮助。 I was finally able to make this work. 我终于能够做到这一点。 Below is the working version: 以下是工作版本:

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;
}

I tried the code below with "abc", "abcd", and "abcde" and the C# code returns the same value as for the C++ code: 我用“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;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM