I am trying to hash an unsigned long
value, but the hash function takes an unsigned char *
, as seen in the implementation below:
我试图散列一个未签名的长值,但哈希函数采用无符号的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;
}
Is there a way I can achieve my goal, perhaps with a cast between the two?
有没有一种方法可以让我实现我的目标,也许是在两者之间的转换?
6 个解决方案
#1
11
unsigned long x;
unsigned char * p = (unsigned char*)&x;
Make sure you use all 4 bytes through the p
, or whatever is the length of unsigned long
on your system.
确保您使用了所有4字节的p,或任何长度的无符号长在您的系统上。
#2
1
Technically you can achieve it with:
技术上你可以做到:
unsigned long value = 58281;
djb2((unsigned char *) &value, sizeof(value));
Mind the usual pitfalls, however:
不过要注意常见的陷阱:
- The hash function in question was originally meant for strings (hence the prototype), so make sure it fits your needs (# of collisions, avalanching, etc.)
- 问题中的哈希函数最初是用于字符串(因此原型),所以要确保它符合您的需求(冲突的#,雪崩,等等)。
- If at some point you want to hash very large objects for which
sizeof(object) > (int) sizeof(object)
(if applicable on your architecture(s)), note you might get out of bounds accesses (undefined behaviour) or only part of your object hashed. - 如果在某个点上,您想要散列非常大的对象,以便为其sizeof(object) > (int) sizeof(object)(如果适用于您的体系结构),请注意,您可能会跳出边界访问(未定义的行为),或者是您的对象散列的一部分。
#3
1
As other said, you can easily read an int
or any other object as a char
array :
正如其他人所说,您可以很容易地将int或任何其他对象读取为char数组:
unsigned char value = 0xde;
unsigned short value = 0xdead;
unsigned long value = 0xdeadbeef;
double value = 1./3;
djb2((unsigned char*)&value, sizeof value);
But note that 0xdead
stored in a short
or a long
won't have the same hash.
但是请注意,在短时间或长时间内存储的0xdead不会有相同的散列。
Also note that your hash function could be better unrolled using a Duff's device :
还要注意,使用Duff的设备可以更好地展开哈希函数:
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;
}
#4
0
This shows a cast working. Note that in this case the "ABC" string will be null terminated but this may require more care in real world cases
这显示了一个演员的工作。请注意,在这种情况下,“ABC”字符串将被终止,但这可能需要在现实世界中更多的关注。
#include <stdio.h>
int main() {
unsigned long x=0x414243; #0x414243 is ABC
unsigned char *s=(unsigned char *)&x;
printf("%s", s);
}
#5
0
Since you've posted your code now, you'd want to use something similar to this:
既然你现在已经发布了你的代码,你会想要使用类似的东西:
#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;
}
#1
11
unsigned long x;
unsigned char * p = (unsigned char*)&x;
Make sure you use all 4 bytes through the p
, or whatever is the length of unsigned long
on your system.
确保您使用了所有4字节的p,或任何长度的无符号长在您的系统上。
#2
1
Technically you can achieve it with:
技术上你可以做到:
unsigned long value = 58281;
djb2((unsigned char *) &value, sizeof(value));
Mind the usual pitfalls, however:
不过要注意常见的陷阱:
- The hash function in question was originally meant for strings (hence the prototype), so make sure it fits your needs (# of collisions, avalanching, etc.)
- 问题中的哈希函数最初是用于字符串(因此原型),所以要确保它符合您的需求(冲突的#,雪崩,等等)。
- If at some point you want to hash very large objects for which
sizeof(object) > (int) sizeof(object)
(if applicable on your architecture(s)), note you might get out of bounds accesses (undefined behaviour) or only part of your object hashed. - 如果在某个点上,您想要散列非常大的对象,以便为其sizeof(object) > (int) sizeof(object)(如果适用于您的体系结构),请注意,您可能会跳出边界访问(未定义的行为),或者是您的对象散列的一部分。
#3
1
As other said, you can easily read an int
or any other object as a char
array :
正如其他人所说,您可以很容易地将int或任何其他对象读取为char数组:
unsigned char value = 0xde;
unsigned short value = 0xdead;
unsigned long value = 0xdeadbeef;
double value = 1./3;
djb2((unsigned char*)&value, sizeof value);
But note that 0xdead
stored in a short
or a long
won't have the same hash.
但是请注意,在短时间或长时间内存储的0xdead不会有相同的散列。
Also note that your hash function could be better unrolled using a Duff's device :
还要注意,使用Duff的设备可以更好地展开哈希函数:
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;
}
#4
0
This shows a cast working. Note that in this case the "ABC" string will be null terminated but this may require more care in real world cases
这显示了一个演员的工作。请注意,在这种情况下,“ABC”字符串将被终止,但这可能需要在现实世界中更多的关注。
#include <stdio.h>
int main() {
unsigned long x=0x414243; #0x414243 is ABC
unsigned char *s=(unsigned char *)&x;
printf("%s", s);
}
#5
0
Since you've posted your code now, you'd want to use something similar to this:
既然你现在已经发布了你的代码,你会想要使用类似的东西:
#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;
}