简体   繁体   English

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

[英]Objective-C : Fowler–Noll–Vo (FNV) Hash implementation

I have a HTTP connector in my iPhone project and queries must have a parameter set from the username using the Fowler–Noll–Vo (FNV) Hash. 我的iPhone项目中有一个HTTP连接器,并且查询中必须使用Fowler-Noll-Vo(FNV)哈希从用户名中设置参数。

I have a Java implementation working at this time, this is the code : 我目前有一个Java实现正在工作,这是代码:

long fnv_prime = 0x811C9DC5;
long hash = 0;

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

Now on the iPhone side, I did this : 现在在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];
}

This script doesn't give me the same result has the Java one. 这个脚本给我的结果与Java的不同。

In first loop, I get this : 在第一个循环中,我得到了:

hash = 0 杂凑= 0

hash = 100 (first letter is "d") 哈希= 100(首字母为“ d”)

hash = 1865261300 (for hash = 100 and fnv_prime = -2128831035 like in Java) 哈希= 1865261300(对于哈希= 100和fnv_prime = -2128831035,如Java中一样)

Do someone see something I'm missing ? 有人看到我想念的东西吗?

Thanks in advance for the help ! 在此先感谢您的帮助 !

In Java, this line: 在Java中,此行:

long fnv_prime = 0x811C9DC5;

will yield in fnv_prime the numerical value -2128831035, because the constant is interpreted as an int , which is a 32-bit signed value in Java. 将在fnv_prime产生数字值-2128831035,因为常量被解释为int ,这是Java中的32位带符号值。 That value is then sign-extended when written in a long . 当以long写入时,该值将被符号扩展。

Conversely, in the Objective-C code: 相反,在Objective-C代码中:

int64_t fnv_prime = 0x811C9DC5;

the 0x811C9DC5 is interpreted as an unsigned int constant (because it does not fit in a signed 32-bit int ), with numerical value 2166136261. That value is then written into fnv_prime , and there is no sign to extend since, as far as the C compiler is concerned, the value is positive. 0x811C9DC5被解释为一个unsigned int常量(因为它不适合有符号的32位int ),其数值为fnv_prime然后将该值写入fnv_prime ,并且没有扩展的符号,因为就C编译器而言,该值为正。

Thus you end up with distinct values for fnv_prime , which explains your distinct results. 因此,您最终得到fnv_prime不同值,这说明了不同的结果。

This can be corrected in Java by adding a " L " suffix, like this: 在Java中,可以通过添加“ L ”后缀来纠正此问题,如下所示:

long fnv_prime = 0x811C9DC5L;

which forces the Java compiler to interpret the constant as a long , with the same numerical value than what you get with the Objective-C code. 这迫使Java编译器将常量解释为long ,其数值与使用Objective-C代码获得的数值相同。

Incidentally, 0x811C9DC5 is not a FNV prime (it is not even prime); 顺便说一句,0x811C9DC5 不是 FNV素数(甚至不是素数)。 it is the 32 bit FNV "offset basis". 它是32位FNV“偏移量基础”。 You will get incorrect hash values if you use this value (and more hash collisions). 如果使用此值(以及更多的哈希冲突),则会得到不正确的哈希值。 The correct value for the 32 bit FNV prime is 0x1000193. 32位FNV素数的正确值为0x1000193。 See http://www.isthe.com/chongo/tech/comp/fnv/index.html 参见http://www.isthe.com/chongo/tech/comp/fnv/index.html

将32位值0x811C9DC5分配给64位var的符号扩展有所不同。

Are the characters in Java and Objective-c the same? Java和Objective-c中的字符是否相同? NSString will give you unichars. NSString会给你unichars。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM