5

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);
}

今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

hash = 100(最初の文字は「d」です)

hash = 1865261300(Javaのようにhash=100およびfnv_prime=-2128831035の場合)

誰かが私が欠けているものを見ますか?

助けてくれてありがとう!

4

4 に答える 4

4

Javaでは、次の行があります。

long fnv_prime = 0x811C9DC5;

定数はJavaでは32ビットの符号付き値であるfnv_primeとして解釈されるため、数値-2128831035になります。intその値は、で記述されたときに符号拡張されlongます。

逆に、Objective-Cコードでは:

int64_t fnv_prime = 0x811C9DC5;

これは、数値21661362610x811C9DC5の定数として解釈されますunsigned int(符号付き32ビットに収まらないため)。次に、その値がに書き込まれ、Cコンパイラに関する限り、拡張する符号はありません。値は正です。intfnv_prime

したがって、最終的にはの値が異なりfnv_prime、これが結果を説明します。

Lこれは、Javaで次のように""サフィックスを追加することで修正できます。

long fnv_prime = 0x811C9DC5L;

これにより、Javaコンパイラはlong、Objective-Cコードで取得したものと同じ数値で、定数をとして解釈するように強制されます。

于 2010-05-18T11:20:11.037 に答える
2

ちなみに、0x811C9DC5はFNVプライムではありません(プライムでもありません)これは、32ビットFNVの「オフセットベース」です。この値(およびより多くのハッシュ衝突)を使用すると、誤ったハッシュ値が取得されます。32ビットFNVプライムの正しい値は0x1000193です。http://www.isthe.com/chongo/tech/comp/fnv/index.htmlを参照してください

于 2012-12-01T09:31:57.217 に答える
1

これは、32ビット値0x811C9DC5を64ビット変数に割り当てる符号拡張の違いです。

于 2010-05-18T11:36:49.000 に答える
0

JavaとObjective-cの文字は同じですか?NSStringはあなたにunicharsを与えます。

于 2010-05-18T10:59:29.007 に答える