2010-12-07 2 views
0

У меня есть строка, для которой я вычислить sha1 переваривать так:Сравнить часть sha1 переваривать с шестнадцатеричной строки в C

SHA1(sn, snLength, sha1Bin); 

Если я правильно это приводит к 20 байт полукокса (с двоичными данными). Я хочу сравнить последние 3 байта этого символа с другим символом. Этот символ содержит строку «6451E6». 64, 51 & E6 - шестнадцатеричные значения. Как преобразовать «6451E6», так что я могу сравнить его с помощью:

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

{ 

} 

У меня есть эта функция:

/* 
* 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); 
} 

, который делает то же самое, но я новичок в C и не понимаю, это :-(

+0

Это `char *`, а не `char`. – 2010-12-07 21:21:40

ответ

1

Фикс для кода AShelly в:

#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")); 
} 
3

легче идти другой путем - преобразования двоичных данных в шестнадцатеричной строку для сравнения:

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

Даже если вы предпочитаете преобразовывать в двоичный код, sscanf(...%2x...) лучше, чем вручную разбор шестнадцатеричных чисел.

+0

Возможно, это правда, но скорость очень важна (19000000 итераций), и я бы хотел не касаться части sha1Bin. theVarWithHexValues ​​с другой стороны const. Любые другие предложения? – tersmitten 2010-12-07 21:27:40

+1

Я подозреваю, что пропускная способность памяти будет доминировать, поэтому эта версия может вас удивить. Или это может не так, просто не предполагайте ничего. Кроме того, я не знаю, что вы подразумеваете под «касанием части sha1Bin». Мой код не изменяет sha1Bin. – 2010-12-07 21:32:50

0
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) 
+0

Это неправильно в архитектуре большого конца, потому что первый байт будет высоким байтом с нулевым значением и неправильным для архитектуры little-endian, потому что байты будут отменены. – 2010-12-07 21:46:38

1

theVarWithHexValues Если действительно постоянная какой-то, то проще всего было бы поставить его в двоичную форму непосредственно. Вместо того, чтобы:

const char *theVarWithHexValues = "6451E6"; 

использования:

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

... то вы можете просто memcmp() непосредственно.

Смежные вопросы