Objective-C:Fowler-Noll-Vo(FNV)哈希实现

Dou*_*ugh 5 iphone hash objective-c fnv

我的iPhone项目中有一个HTTP连接器,查询必须使用Fowler-Noll-Vo(FNV)哈希从用户名中设置参数集.

我这时有一个Java实现,这是代码:

long fnv_prime = 0x811C9DC5;
long hash = 0;

for(int i = 0; i < str.length(); i++)
{
    hash *= fnv_prime;
    hash ^= str.charAt(i);
}
Run Code Online (Sandbox Code Playgroud)

现在在iPhone方面,我这样做了:

int64_t fnv_prime = 0x811C9DC5;
int64_T hash = 0;

for (int i=0; i < [myString length]; i++)
{
    hash *= fnv_prime;
    hash ^= [myString characterAtIndex:i];
}
Run Code Online (Sandbox Code Playgroud)

这个脚本没有给我与Java一样的结果.

在第一个循环中,我得到了这个:

hash = 0

hash = 100(首字母是"d")

hash = 1865261300(对于hash = 100和fnv_prime = -2128831035,如Java)

有人看到我失踪的东西吗?

在此先感谢您的帮助 !

Tho*_*nin 4

在 Java 中,这一行:

long fnv_prime = 0x811C9DC5;
Run Code Online (Sandbox Code Playgroud)

将产生fnv_prime数值 -2128831035,因为该常量被解释为 an int,它是 Java 中的 32 位有符号值。当写入 a 时,该值将被符号扩展long

相反,在 Objective-C 代码中:

int64_t fnv_prime = 0x811C9DC5;
Run Code Online (Sandbox Code Playgroud)

the0x811C9DC5被解释为一个unsigned int常量(因为它不适合有符号的 32 位int),数值为 2166136261。然后将该值写入fnv_prime,并且没有符号可以扩展,因为就 C 编译器而言,该值为正。

因此,您最终会得到 的不同值fnv_prime,这解释了您的不同结果。

在 Java 中可以通过添加“ L”后缀来纠正此问题,如下所示:

long fnv_prime = 0x811C9DC5L;
Run Code Online (Sandbox Code Playgroud)

这会强制 Java 编译器将常量解释为 a long,其数值与使用 Objective-C 代码获得的数值相同。