У меня есть коннектор HTTP в моем проекте iPhone, и запросам нужно было установить параметр от имени пользователя с помощью 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);
}
Теперь на стороне 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];
}
Этот сценарий не дает мне, тот же результат имеет Java один.
В первом цикле я получаю это:
хешируйте = 0
хешируйте = 100 (первая буква является "d"),
хешируйте = 1865261300 (для хеша = 100 и fnv_prime =-2128831035 как в Java)
Кто-то видит что-то, что я пропускаю?
Заранее спасибо за справку!
В Java эта строка:
long fnv_prime = 0x811C9DC5;
вернет в fnv_prime
числовое значение -2128831035, потому что константа интерпретируется как int
, который представляет собой 32-битное знаковое значение в Java. Это значение затем расширяется по знаку, если записано в длинное
.
И наоборот, в коде Objective-C:
int64_t fnv_prime = 0x811C9DC5;
0x811C9DC5
интерпретируется как константа unsigned int
(потому что она не помещается в 32-битный знаковый ] int
) с числовым значением 2166136261. Это значение затем записывается в fnv_prime
, и нет знака для расширения, поскольку для компилятора C значение положительное.
Таким образом, вы получаете разные значения для fnv_prime
, что объясняет ваши отличные результаты.
Это можно исправить в Java, добавив суффикс « L
», например:
long fnv_prime = 0x811C9DC5L;
, который заставляет компилятор Java интерпретировать константу как long
с то же числовое значение, что и в коде Objective-C.
Это разница в расширении знака, когда 32-битное значение 0x811C9DC5 присваивается 64-битной переменной.
Одинаковы ли символы в Java и Objective-c? NSString даст вам unichars.