views:

227

answers:

3

Hello I have an unsigned char * that looks (after printf) like this (it's a SHA-1 hash):

n\374\363\327=\3103\231\361P'o]Db\251\360\316\203

I need to convert this unsigned char * to an unsigned int, what do you think it would be the best way to do it ? I have some ideas, but I'm not a C expert so wanted to see someone else ideas before trying my own stuff.

+1  A: 

That's 160 bits, so would be hard to fit in a single unsigned int. However, it'd certainly be possible to fit it into an array of unsigned ints.

Something like this (ugly, makes a couple of assumptions about machine architecture, should probably use CHAR_BITS and a couple of other things compile-time to have the right constants, but should be enough as a proof-of-concept):

unsigned int (*convert)(unsigned char *original)
{
  unsigned int *rv = malloc(5*sizeof(unsigned int));
  char *tp = original;

  for (rvix=0;rvix<5;rvix++) {
    rv[rvix] = *(tp++)<<24;
    rv[rvix] |= *(tp++)<<16;
    rv[rvix] |= *(tp++)<<8;
    rv[rvix] |= *(tp++);
  }

  return rv;
}
Vatine
I think that your code got cut ? could you re-paste that ? :-)
Mr.Gando
Yes, classic case of "oops, < introduces a tag".
Vatine
Thanks vatine, will your idea!
Mr.Gando
+3  A: 

Well, that's more than 4 bytes, so if your system uses 32 bits for an unsigned int you can't do it without potentially losing information. IOW, it will have to be a hash of some kind.

T.E.D.
+2  A: 

Why would you need a conversion? It's a 160 bit long digest. Digests are used only in two ways:

You print a digest with something like

for (i = 0; i < 20; ++i) {
    printf("%2x", digest[i]);
}

and compare against another digest with something like

for (i = 0, equals = 1; i < 20; ++i) {
    if (a[i] != b[i]) {
        equals = 0;
    }
}

It works just fine the way it is as a 20-byte long array of bytes. You don't have to worry about endianness, word length, nothing.

Tadeusz A. Kadłubowski
The problem is that a SHA-1 String is 160 bytes... what I'm thinking is I could use an array of 5 32bit ints to hold the whole SHA-1 string and make a dedicated Class to handle the comparison operations etc.
Mr.Gando
@Mr. Gando: What's the difference between an array of 20 characters and an array of 5 ints, for practical purposes? It's not like you're using the ints as ints, just as 20 bytes of storage. Wrapping a digest in a class is a good idea, but using an array of ints rather than characters is pointless.
David Thornley
@David: I agree. Besides, chars are (almost) always 8 bit long (you can always check CHAR_BIT, if you really need to be uber-portable), whereas unsigned ints can have different sizes on different machines, packed in different byte order etc. Extra complexity for little gain.
Tadeusz A. Kadłubowski
@ David : What if for your particular implementation you used the ints as ints ?
Mr.Gando