tersmitten
tersmitten

Reputation: 1330

Compare part of sha1 digest with hex string in C

I have a string for which I compute a sha1 digest like this:

SHA1(sn, snLength, sha1Bin);

If I'm correct this results in a 20 byte char (with binary data). I want to compare the last 3 bytes of this char with another char. This char contains the string "6451E6". 64, 51 & E6 are hex values. How do I convert "6451E6" so that I can compare it via:

if(memcmp(&sha1Bin[(20 - 3)], theVarWithHexValues, 3) == 0)

{

}

I have this function:

/*
 * convert hexadecimal ssid string to binary
 * return 0 on error or binary length of string
 *
 */
u32 str2ssid(u8 ssid[],u8 *str) {
    u8 *p,*q = ssid;
    u32 len = strlen(str);

    if( (len % 2) || (len > MAX_SSID_OCTETS) )
      return(0);

    for(p = str;(*p = toupper(*p)) && (strchr(hexTable,*p)) != 0;) {

      if(--len % 2) {
        *q = ((u8*)strchr(hexTable,*p++) - hexTable);
        *q <<= 4;
      } else {
        *q++ |= ((u8*)strchr(hexTable,*p++) - hexTable);
      }
    }
    return( (len) ? 0 : (p - str) / 2);
}

which does the same but I'm new to C and don't understand it :-(

Upvotes: 0

Views: 2231

Answers (4)

caf
caf

Reputation: 239181

If theVarWithHexValues is indeed a constant of some sort, then the easiest thing would be to put it into binary form directly. Instead of:

const char *theVarWithHexValues = "6451E6";

use:

const char *theVarWithHexValues = "\x64\x51\xE6";

...then you can just memcmp() directly.

Upvotes: 1

Steve Jessop
Steve Jessop

Reputation: 279325

Fix for AShelly's code:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int hashequal(const unsigned char *sha1Bin, const char *hexstr) {
    unsigned long hexvar = strtoul(hexstr, NULL, 16);
    unsigned char theVarWithHexValues[] = { hexvar >> 16, hexvar >> 8, hexvar };
    return memcmp(sha1Bin + 17, theVarWithHexValues, 3) == 0;
}

int main() {
    unsigned char sha1Bin[20];
    sha1Bin[17] = 0x64;
    sha1Bin[18] = 0x51;
    sha1Bin[19] = 0xE6;
    printf("%d\n", hashequal(sha1Bin, "6451E6"));
    printf("%d\n", hashequal(sha1Bin, "6451E7"));
}

Upvotes: 1

AShelly
AShelly

Reputation: 35580

char* hexstr = "6451E6";
unsigned long hexvar = strtoul(hexstr, NULL, 16);
hexvar = htonl(hexvar)<<8;  //convert to big-endian and get rid of zero byte.

memcmp(&sha1Bin[(20 - 3)], (char*)hexvar, 3)

Upvotes: 0

Marcelo Cantos
Marcelo Cantos

Reputation: 185972

It's easier to go the other way — convert the binary data to a hex string for comparison:

char suffix[7];
sprintf(suffix, "%02x%02x%02x", sha1Bin[17], sha1Bin[18], sha1Bin[19]);
return stricmp(suffix, theVarWithHexValues) == 0;

Even if you prefer converting to binary, sscanf(...%2x...) is better than manually parsing hex numbers.

Upvotes: 3

Related Questions