我遇到了这个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;
}
答案 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;
}