How to cast long unsigned to unsigned char*?

34,984

Solution 1

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.

Solution 2

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.

Solution 3

As other said, you can easily read an int or any other object as a char array :

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.

Also note that your hash function could be better unrolled using a Duff's device :

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;
}
Share:
34,984
James
Author by

James

Updated on May 14, 2020

Comments

  • James
    James almost 4 years

    I am trying to hash an unsigned long value, but the hash function takes an unsigned char *, as seen in the implementation below:

    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?