[英]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.