2

値をハッシュしようとしていますが、以下の実装に見られるように、unsigned longハッシュ関数は を受け取ります:unsigned char *

unsigned long djb2(unsigned char *key, int n)
{
    unsigned long hash = 5381;
    int i = 0;
    while (i < n-8) {
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
        hash = hash * 33 + key[i++];
    }
    while (i < n)
        hash = hash * 33 + key[i++];
    return hash;
}

おそらく2つの間のキャストで、目標を達成できる方法はありますか?

4

6 に答える 6

13
unsigned long x;

unsigned char * p = (unsigned char*)&x;

で 4 バイトすべてを使用するpか、システム上の の長さをunsigned long確認してください。

于 2013-05-14T07:12:26.383 に答える
1

int他の人が言ったように、または他のオブジェクトをchar配列として簡単に読み取ることができます。

unsigned char value = 0xde;
unsigned short value = 0xdead;
unsigned long value = 0xdeadbeef;
double value = 1./3;

djb2((unsigned char*)&value, sizeof value);

ただし、 aまたは aに0xdead格納されているものは同じハッシュを持たないことに注意してください。shortlong

また、ハッシュ関数は、ダフのデバイスを使用してより適切に展開できることに注意してください。

unsigned long djb2(unsigned char *k, int size)
{
    unsigned long h = 5381;
    int i = 0;
    switch(size % 8) {
      case 0: while(i < size) { 
                  h = h*33 + k[i++];
      case 7:     h = h*33 + k[i++];
      case 6:     h = h*33 + k[i++];
      case 5:     h = h*33 + k[i++];
      case 4:     h = h*33 + k[i++];
      case 3:     h = h*33 + k[i++];
      case 2:     h = h*33 + k[i++];
      case 1:     h = h*33 + k[i++];
              }
    }
    return h;
}
于 2013-05-14T09:17:42.877 に答える
1

技術的には、次の方法で実現できます。

unsigned long value = 58281;
djb2((unsigned char *) &value, sizeof(value));

ただし、よくある落とし穴に注意してください。

  • 問題のハッシュ関数はもともと文字列用でした (したがってプロトタイプ) ため、ニーズに合っていることを確認してください (衝突の数、なだれなど)。
  • ある時点で非常に大きなオブジェクトをハッシュしたいsizeof(object) > (int) sizeof(object)場合 (アーキテクチャに該当する場合)、範囲外のアクセス (未定義の動作) またはオブジェクトの一部のみがハッシュされる可能性があることに注意してください。
于 2013-05-14T07:56:35.527 に答える
0

これは、キャストが機能していることを示しています。この場合、「ABC」文字列は null で終了しますが、実際のケースではより注意が必要になる場合があることに注意してください。

#include <stdio.h>

int main() {
    unsigned long x=0x414243;  #0x414243 is ABC
    unsigned char *s=(unsigned char *)&x;
    printf("%s", s);
}
于 2013-05-14T07:23:40.050 に答える
0

コードを投稿したので、次のようなものを使用する必要があります。

#include <stdio.h>


int main() {
    unsigned long result, x = 0xdeadbeef;
    x = convert_endian(x);

    result = djb2((unsigned char*)&x, sizeof(x));
    do_something(result);
    return 0;
}
于 2013-05-14T07:33:00.347 に答える
-2

ultoa_sを使用して変換する必要があります

于 2013-05-14T07:13:41.547 に答える