簡體   English   中英

C#這個C哈希函數的等價物

[英]C# Equivalent of this C hash function

我遇到了這個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;
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM