Символьный указатель добавления случайных значений при присоединении строковых символов - PullRequest
0 голосов
/ 23 февраля 2019

Я использую следующий код для печати md5 и создаю строку

char *hash = (char*)malloc(32 * sizeof(char));
unsigned *d = md5(msg, strlen(msg));
MD5union u;
printf("\n\n\nThe MD5 code for input string is : \n");
for (j=0;j<4; j++){
    u.w = d[j];
    for (k=0;k<4;k++) 
    {
        char *mVal = (char*)malloc(sizeof(char));
        sprintf(mVal, "%02x",u.b[k]);
        strcat(hash, mVal);
        printf("%02x",u.b[k]);
    }
}

printf("\n\n\nThe MD5 code for input string is :%s \n", hash);

Мой вывод

The MD5 code for input string is : 
187ef4436122d1cc2f40dc2b92f0eba0


The MD5 code for input string is :p��187ef4436122d1cc2f40dc2b92f0eba0 

Почему в моем хэш-значении p�� дополнительно

1 Ответ

0 голосов
/ 23 февраля 2019

hash не инициализируется.Может иметь любое начальное значение.strcat добавляет данные.Если в hash есть что-то, что квалифицируется как строка с нулевым символом в конце, оно не будет удалено.Используйте strcpy или инициализируйте нулями hash перед использованием.

За исключением этого, в вашем коде есть несколько ошибок и неопределенное поведение.

  1. malloc(32 * sizeof(char)); выделяет память дляСтрока длиной 31 (не 32) символов при включении нулевого символа завершения.Если вы хотите сохранить md5 в виде строки, выделите 33 байта памяти.
  2. char *mVal = (char*)malloc(sizeof(char)); sprintf(mVal, "%02x",u.b[k]); - в памяти есть место для строки длиной 0 (не 1, не 2, а нулевой), указывающей на mVal.Если вы хотите сохранить выходные данные sprintf, "%02x" в переменной, выделите как минимум 3 байта памяти - первый байт для первой шестнадцатеричной цифры, второй байт для второй шестнадцатеричной цифры и третий байт для нулевого символа завершения.
  3. char *mVal = (char*)malloc(sizeof(char)); нигде не освобождается, пока не выйдет из области видимости и просто утечет память.
  4. Похоже, вы используете md5hash.c .Функция возвращает указатель на static память.Это плохо, поскольку делает функцию не входящей повторно.
  5. Ваша программа может быть переписана так: char *hash = malloc(33); unsigned *d = md5(msg, strlen(msg)); snprintf(hash, 33, "%08x%08x%08x%08x", d[0], d[1], d[2], d[3]);.Нет необходимости конвертировать unsigned int в unsigned char при печати в шестнадцатеричном формате, вы можете сделать это напрямую с помощью %08xunsigned char преобразуется обратно в int при передаче в качестве аргумента printf.И вы можете просто sprintf непосредственно в hash, не требуя временных переменных.
  6. Использование объединения для преобразования массива unsigned int в байты ощущается как злоупотребление инструментом.(В большинстве систем) вы можете просто привести указатель char *d_as_char = (void*)d; и получить доступ к d_as_char как массив символов 4 * sizeof(int).Если вы действительно хотите, чтобы в вашем коде не было неопределенного поведения и алиасов, используйте способ memcpy: char d_as_array[sizeof(int) * 4]; memcpy(d_as_array, d, sizeof(d_as_array));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...