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