Как сохранить шестнадцатеричное значение, сгенерированное MD5, как целое число? - PullRequest
0 голосов
/ 17 февраля 2012

Я использую следующий код для генерации хеша MD5 для строки.Значение, напечатанное в шестнадцатеричном формате, кажется правильным (я проверил его на веб-сайте для той же строки).Однако, когда я печатаю значение как целое число, оно имеет 36 цифр.Насколько я понимаю, он должен иметь 16 цифр, потому что сгенерированный хэш имеет длину 128 бит.

Я хочу знать, как должно выполняться преобразование из unsigned char в int и как его можно сохранить в переменной, чтобы в конечном итоге его можно было распечатать в файл.

Было бы хорошо, если бы кто-то мог объяснить, как значения хранятся в беззнаковом символе, например, сколько бит требуется, чтобы представить одну цифру шестнадцатеричного и десятичного числа, и как я могу преобразовать между ними.Я пробовал sscanf и strtol, но я думаю, что я не правильно их использую.

    int main (void)
    {
      char *str = "tell";
      u_int8_t *output; //unsigned char
      output = malloc(16 * sizeof(char));
      int i = 0;
      MD5_CTX ctx;
      MD5Init(&ctx);
      MD5Update(&ctx, str, strlen(str));
      MD5Final(output, &ctx);

      while(i < 16)
        printf("%x",output[i++]);
      printf("\n");
      i = 0;
      while(i < 16)
        printf("%i",output[i++]);
      printf("\n");
    }

Вывод здесь

fe17ec3c451f132ef82a3a54e84a461e
254232366069311946248425884232747030

Ответы [ 2 ]

3 голосов
/ 17 февраля 2012

Вы печатаете десятичное значение каждого байта (254, 23, 236, ...), а не одно 128-битное значение, преобразованное в целое число. Ваш цикл должен выглядеть примерно так: value <<= 8; value+=output[i++] (при условии, что ваш value - это тип, который может вместить такое большое число).

Ваше ожидание того, сколько цифр должно быть в результате, также отключено; если вы не печатаете начальные нули, его длина может быть от 1 до len (2 ** 128-1), что составляет 39 десятичных цифр.

Кстати, вы также должны дополнять нулями свой шестнадцатеричный вывод, иначе любой байт со значением ниже 16 напечатает одну шестнадцатеричную цифру (printf("%02x",...)).

3 голосов
/ 17 февраля 2012

Вы не можете хранить 128-битное значение в int (если int не меньше 128 бит в вашей реализации C, что, я уверен, предсказывает, что это не так).То же самое касается long long, самого большого стандартного целочисленного типа.

Десятичное значение, которое вы напечатали, равно «254» (десятичное для 0xfe), за которым следует «23» (десятичное для 0x17), и так далее.Это в основном бессмысленно - если вы представляете либо 0x010001 , либо 0x0A01, как это, вы получите ту же строку, 101.Вы получили 36 цифр, потому что это общее количество десятичных цифр в каждом из 16-байтовых значений.

Вы напечатали шестнадцатеричное значение длиной 32 символа (4 бита на символ, 32 символа, 128биты).Это на самом деле немного удачи, каждый байт в вашем дайджесте, по крайней мере, равен 0x10.Вы должны печатать с %02x, чтобы включить отрыв 0 для небольших значений.

Если вы хотите представить 128-битное значение в виде десятичной строки, то вам нужна либо библиотека bignum, либо длинное деление.Но бессмысленно выражать контрольные суммы MD5 в десятичном виде: когда люди представляют их в виде строк, они всегда используют шестнадцатеричные значения.

Было бы хорошо, если бы кто-то мог объяснить, как значения хранятся в неподписанном символе

8 битов дайджеста в каждом unsigned char, 16 беззнаковых символов в массиве, составляет 128 битов.Вы не можете использовать sscanf или strtol, потому что значение, хранящееся в MD5Final, не является строкой.

...