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

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

但是,有一点不对劲。这 2 个函数不会产生相同的结果。

编辑

感谢所有评论和帮助。我终于能够完成这项工作。以下是工作版本:

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

最佳答案

我用“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;
        }

关于这个 C 哈希函数的 C# 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30110822/

相关文章:

c# - 查找特定子字符串中匹配的多个组

c - #define REG(x) (*((volatile unsigned int *)(x)))

c - 快速排序逻辑无法正常工作

c - 使用 fgets() 时出现段错误

C# - using 语句的位置

c# - 如何在 Visual Studio 2010 的 C# 中使用 OpenFileDialog

c# - 直接通过返回码声明和初始化之间有什么区别吗?

c# - 自动取消订阅事件

c++ - 一次加和乘 x*y+z 的 cmath 函数

c - Dev-c++编译错误对象