два разных хеш-значения для одной строки - PullRequest
1 голос
/ 06 января 2012

Мне нужно сравнить хеш-значения двух строк.Я использую строку «шаблон» для тестирования.Но я получил разные значения хеш-функции для этой строки, поэтому она не всегда одинакова.Я использую CryptoApi и MD4

int _tmain(int argc, _TCHAR* argv[])
{
    std::hash_map<int,int> table;
    HCRYPTPROV hProv1,hProv2;
    BYTE *pbBuffer1=(BYTE*)"template";//data to hash
    DWORD dwBufferLen1=strlen((char*)pbBuffer1)+1;
    HCRYPTHASH hHash1,hHash2;
    //first hash
    CryptAcquireContext(&hProv1,NULL,NULL,PROV_RSA_AES,0);
    CryptCreateHash(hProv1,CALG_MD4,0,0,&hHash1);
    CryptHashData(hHash1,pbBuffer1,dwBufferLen1,0);
    /*---------*/
    BYTE *pbBuffer2=(BYTE*)"template";//data to hash
    DWORD dwBufferLen2=strlen((char*)pbBuffer2)+1;
    //second hash
    CryptAcquireContext(&hProv2,NULL,NULL,PROV_RSA_AES,0);  
    CryptCreateHash(hProv2,CALG_MD4,0,0,&hHash2);
    CryptHashData(hHash2,pbBuffer2,dwBufferLen2,0);
    if (hHash1==hHash2)
        printf("The Same\n");
    else printf("Not same\n");
    /*---------*/
    std::cout<<hHash1<<std::endl;
    std::cout<<hHash2<<std::endl;
    if (hProv1)
        CryptReleaseContext(hProv1,0);
    if (hProv2)
        CryptReleaseContext(hProv2,0);
    system("pause");
    return 0;
} 

Например, значение хеш-функции в hHash1

691136

Значение хеш-функции в hHash2

691216

Ответы [ 3 ]

4 голосов
/ 06 января 2012

HCRPTHASH - это ULONG_PTR typedef, согласно здесь . Это означает, что это указатель:

Тип данных HCRYPTHASH используется для представления дескрипторов для хеширования объектов. Эти дескрипторы указывают модулю CSP, какой хеш используется в конкретной операции. Модуль CSP не позволяет напрямую манипулировать значениями хеша. Вместо этого пользователь манипулирует хэш-значениями через хэш-дескриптор.

typedef ULONG_PTR HCRYPTHASH;

Сравнение указателей с == примерно так же продуктивно, как прибивать желе (или желе гражданам США) к дереву или пытаться дрессировать кошку: -)

Значения, которые вы видите в качестве своих «хэшей», на самом деле являются указателями с интервалом в 80 байт (поскольку они являются указателями на два разных блока памяти).

Чтобы получить фактический хеш из дескриптора, вам нужно что-то вроде следующего, которое печатает шестнадцатеричные цифры:

CHAR hexDigits[] = "0123456789abcdef";
BYTE md4Hash[MD4LEN];
DWORD cbHash = MD4LEN;
if (CryptGetHashParam (hHash1, HP_HASHVAL, md4Hash, &cbHash, 0)) {
    printf("MD4 hash is: ");
    for (DWORD i = 0; i < cbHash; i++) {
        printf ("%c%c", hexDigits[md4Hash[i] >> 4], hexDigits[md4Hash[i] & 0xf]);
    }
    printf("\n");
} else {
    DWORD dwStatus = GetLastError();
    printf ("CryptGetHashParam failed with code %d\n", dwStatus); 
}

Для сравнения двух значений хеша вы можете сделать:

BYTE md4Hash1[MD4LEN], md4Hash2[MD4LEN];
DWORD cbHash1 = MD4LEN, cbHash2 = MD4LEN;

CryptGetHashParam (hHash1, HP_HASHVAL, md4Hash1, &cbHash1, 0);
CryptGetHashParam (hHash2, HP_HASHVAL, md4Hash2, &cbHash2, 0);

if ((cbHash1 == cbHash2) &&
    (memcmp (md4Hash1, md4Hash2, cbHash1) == 0))
{
    // they are equal.
}
2 голосов
/ 06 января 2012

hHash1 и hHash2 - это не хэш-коды, а дескрипторы.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379908(v=vs.85).aspx

1 голос
/ 06 января 2012

Как уже отмечалось в других ответах, hHash1 и hHash2 являются непрозрачными ручками & mdash; сравнивать их бессмысленно, так как сравнивать адреса двух разных объектов, имеющих одинаковое значение.

Используйте CryptGetHashParam, чтобы получить хеш-значения и сравнить их вместо:

Функция CryptGetHashParam извлекает данные, которые управляют операциями хеш-объекта. Фактическое значение хеш-функции можно получить с помощью этой функции.

...