Распечатка DWORD в шестнадцатеричном формате возвращает 0x7FFFFFFFF в win32 С++

В настоящее время я работаю над приложением win32, которое использует хэш sha1 для строк для генерации ключей для моей карты. Я хочу использовать хэш как DWORD, чтобы я мог выполнять некоторые вычисления между хешами.

Поскольку хэш sha1 воспроизводит 160-битные хеш-значения, я создал структуру с 5 DWORD (32-бит * 5 = 160).

struct _SHA1_HASH
{
   DWORD dwFirst;
   DWORD dwSecond;
   DWORD dwThird;
   DWORD dwFourth;
   DWORD dwFifth;
}SHA1_HASH;

И я хэшировал строку и сохранял ее в структуре.

void GenerateNodeKey()
{
    // SHA-1 Hashing Process
    // ex) strHash = 356A192B7913B04C54574D18C28D46E6395428AB    

    SHA1_HASH key;
    string s_prefix = "0x";
    key.dwFirst = strtol((s_prefix+strHash.substr(0,8)).c_str(), 0, 0); // first 8 bytes
    ...
    ...
    key.dwFifth = strtol((s_prefix+strHash.substr(32,8)).c_str(), 0, 0); // last 8 bytes
}

Но проблема возникла, когда я пытаюсь напечатать значение, чтобы проверить, все ли в порядке.

    wcout << hex 
          << "Node ID : " << key.dwFirst << key.dwSecond << key.dwThird << key.dwFourth << key.dwFifth 
          << dec
          << endl;

Он распечатывается без проблем, если 8-байтовое шестнадцатеричное значение меньше 7FFFFFFF (2 147 483 647). Однако, когда оно больше значения, оно просто выводит максимальное число. Я искал в Интернете, чтобы узнать, насколько велика может быть DWORD, и это не было проблемой (связано: Какое наибольшее целое число с основанием 16 можно хранить в переменной типа dword?)

Кто-нибудь может помочь? Заранее спасибо.


person vaska11    schedule 14.01.2020    source источник
comment
Итак… преобразовать в целое число без знака, которое имеет полный положительный диапазон ваших строк? (Неважно, почему вы получаете хэш со значением string, который, должно быть, уже был преобразован из целых чисел…)   -  person Davis Herring    schedule 14.01.2020
comment
key.dwFirst = std::stoul(strHash.substr(0, 8), nullptr, 16); . Вы можете использовать базовый аргумент для stoul или strtoul вместо добавления 0x   -  person M.M    schedule 14.01.2020


Ответы (1)


Функция strtol возвращает длинное целое число со знаком, которое в Windows имеет диапазон -2 147 483 648 до 2 147 483 647.

Если strtol обнаружит, что сгенерированное число выходит за пределы диапазона, он вернет максимально длинное значение. Из cppreference:

Если преобразованное значение выходит за пределы диапазона соответствующего возвращаемого типа, возникает ошибка диапазона (установка errno в ERANGE) и возвращается LONG_MAX, LONG_MIN, LLONG_MAX или LLONG_MIN.

Вместо этого используйте std::strtoul.

person zdan    schedule 14.01.2020
comment
Ух ты. Спасибо! Это было быстро. Любое предложение по функции, которую я могу использовать для преобразования строки в DWORD? - person vaska11; 14.01.2020
comment
Неважно, я использовал istringsteam для решения проблемы. Спасибо за помощь. - person vaska11; 14.01.2020