2010-05-18 22 views
5

Tôi có trình kết nối HTTP trong dự án iPhone của mình và truy vấn phải có thông số được đặt từ tên người dùng bằng cách sử dụng hàm băm Fowler – Noll – Vo (FNV).Mục tiêu-C: Fowler – Noll – Vo (FNV) Thực hiện băm

Tôi có một thực hiện Java làm việc tại thời điểm này, đây là đoạn code:

long fnv_prime = 0x811C9DC5; 
long hash = 0; 

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

Bây giờ ở phía bên iPhone, tôi đã làm điều này:

int64_t fnv_prime = 0x811C9DC5; 
int64_T hash = 0; 

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

kịch bản này không cho tôi kết quả tương tự có kết quả Java.

Trong vòng đầu tiên, tôi có được điều này:

hash = 0

hash = 100 (chữ cái đầu tiên là "d")

hash = 1865261300 (đối với hash = 100 và fnv_prime = - 2128831035 giống như trong Java)

Có ai đó nhìn thấy thứ tôi đang thiếu không?

Cảm ơn bạn đã trợ giúp!

Trả lời

4

Trong Java, dòng này:

long fnv_prime = 0x811C9DC5; 

sẽ mang lại trong fnv_prime giá trị bằng số -2128831035, bởi vì hằng số được hiểu như là một int, mà là một 32-bit ký giá trị trong Java. Giá trị đó sau đó được gia hạn khi được viết trong một long.

Ngược lại, trong đoạn code Objective-C:

int64_t fnv_prime = 0x811C9DC5; 

các 0x811C9DC5 được hiểu như là một hằng số unsigned int (vì nó không phù hợp trong một ký 32-bit int), với giá trị số 2166136261. Giá trị đó sau đó được viết vào fnv_prime và không có dấu hiệu nào để mở rộng, kể cả trình biên dịch C có liên quan, giá trị là dương.

Vì vậy, bạn kết thúc với các giá trị riêng biệt cho fnv_prime, giải thích kết quả khác biệt của bạn.

Điều này có thể được sửa chữa trong Java bằng cách thêm một "L" hậu tố, như thế này:

long fnv_prime = 0x811C9DC5L; 

mà buộc các trình biên dịch Java để giải thích liên tục như một long, với giá trị bằng số tương tự so với những gì bạn nhận được với mã Objective-C.

+0

Trong Java như trong Obj-C, tôi nhận được cùng một giá trị cho số nguyên tố = -2128831035 Trong Java khi tôi đặt "0x811C9DC5L", tôi nhận giá trị = 2166136261 – Dough

+0

Bạn sẽ không nhận được -2128831035 trong Obj-C. Bạn có chắc chắn đây không phải là một tạo tác của cách bạn in giá trị đó? (tức là bạn đã sử dụng "% lld" hoặc "% d" trong 'printf()'?) –

+0

Và một đầu mối rằng -2128831035 không phải là giá trị số chính xác: nó không phải là số nguyên! -2128831035 = - (3 * 5 * 17 * 101 * 82657) –

0

Các ký tự trong Java và Objective-c có giống nhau không? NSString sẽ cung cấp cho bạn unichars.

+0

Cảm ơn câu trả lời của bạn! Char, trong Java vi Objective-Cn trả về giá trị ASCII của char. Ví dụ: a = 97 b = 98 c = 99 d = 100 và như vậy! – Dough

+0

@dough: chắc chắn không sử dụng ASCII, mặc dù 127 ký tự đầu tiên có thể có cùng giá trị số. Như một bài tập, bạn sẽ nhận được gì nếu bạn in ký tự 'fl'? Và giá trị ASCII của 'fl' là gì? –

+0

'fl' không phải là một nhân vật, nó là hai: f và l! – Dough

1

Sự khác biệt trong phần mở rộng ký hiệu gán giá trị 32 bit 0x811C9DC5 cho biến số 64 bit.

+0

Đó là, thực sự. –

1

Ngẫu nhiên, 0x811C9DC5 là không một nguyên tố FNV (thậm chí không phải là số nguyên tố); nó là cơ sở bù đắp FNV 32 bit ". Bạn sẽ nhận được các giá trị băm không chính xác nếu bạn sử dụng giá trị này (và nhiều xung đột băm). Giá trị đúng cho số nguyên FNV 32 bit là 0x1000193.Xem http://www.isthe.com/chongo/tech/comp/fnv/index.html

Các vấn đề liên quan