C language - Get MD5 hash value / I would like to ask you how to get the hash value of the file by reading the directory stored in the notepad with fgets().

Asked 2 weeks ago, Updated 2 weeks ago, 2 views

#pragma warning ( disable : 4996 )

#include <wchar.h>
#include <windows.h>
#include <Wincrypt.h>
#include <stdio.h>

#define BUFSIZE 1024
#define MD5LEN  16

void file_hash()
{
    char f_list[_MAX_PATH];
    char* t_list;
    int i = 0;

    FILE* fp = fopen("File_list.txt", "r");
    //md5_hash(L"C:\\search\\temp\\Test.txt");

    if (fp == NULL)
    {
        printf("No file.txt");
        exit(1);
    }

    while (!feof(fp))
    {
        t_list = fgets(f_list, _MAX_PATH, fp);
        t_list[strlen(t_list) - 1] = '\0';

        //printf("%s\n", t_list);
        md5_hash(t_list);

    }
    fclose(fp);
}
unsigned long md5_hash(char file_path[])
{
    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HANDLE hFile = NULL;
    BYTE rgbFile[BUFSIZE];
    DWORD cbRead = 0;
    BYTE rgbHash[MD5LEN];
    DWORD cbHash = 0;
    CHAR rgbDigits[] = "0123456789abcdef";
    //const char* filename = ((L"%s", file_path));
    LPCWSTR *filename = file_path;

    // // Logic to check usage goes here.

    hFile = CreateFile(filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_SEQUENTIAL_SCAN,
        NULL);

    if (INVALID_HANDLE_VALUE == hFile)
    {
        dwStatus = GetLastError();
        printf("Error opening file %s\nError: %d\n", filename, dwStatus);
        return dwStatus;
    }

    // // Get handle to the crypto provider
    if (!CryptAcquireContext(&hProv,
        NULL,
        NULL,
        PROV_RSA_FULL,
        CRYPT_VERIFYCONTEXT))
    {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus);
        CloseHandle(hFile);
        return dwStatus;
    }

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
    {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus);
        CloseHandle(hFile);
        CryptReleaseContext(hProv, 0);
        return dwStatus;
    }

    while (bResult = ReadFile(hFile, rgbFile, BUFSIZE,
        &cbRead, NULL))
    {
        if (0 == cbRead)
        {
            break;
        }

        if (!CryptHashData(hHash, rgbFile, cbRead, 0))
        {
            dwStatus = GetLastError();
            printf("CryptHashData failed: %d\n", dwStatus);
            CryptReleaseContext(hProv, 0);
            CryptDestroyHash(hHash);
            CloseHandle(hFile);
            return dwStatus;
        }
    }

    if (!bResult)
    {
        dwStatus = GetLastError();
        printf("ReadFile failed: %d\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CloseHandle(hFile);
        return dwStatus;
    }

    cbHash = MD5LEN;
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
        printf("MD5 hash of file %s is: ", filename);
        for (DWORD i = 0; i < cbHash; i++)
        {
            printf("%c%c", rgbDigits[rgbHash[i] >> 4],
                rgbDigits[rgbHash[i] & 0xf]);
        }
        printf("\n");
    }
    else
    {
        dwStatus = GetLastError();
        printf("CryptGetHashParam failed: %d\n", dwStatus);
    }

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    CloseHandle(hFile);

    return dwStatus;
}

You want to implement a function that reads a directory of files stored in Notepad and calculates hash values and stores the resulting values in variables.

First of all, the Notepad (File_list.txt) is stored in the following format:

C:\search\temp\md5.c

C:\search\temp\md5.h

C:\search\temp\Test.txt

And when you operate file_hash() in main, the following execution result is printed.

Error opening file C:\search\temp\md5.c Error: 2

Error opening file C:\search\temp\md5.h Error: 2

Error opening file C:\search\temp\Test.txt Error: 123

After that, I looked at the contents of the error through googling Error 2 indicates that the system cannot find the specified file. Error 123 has invalid file name, directory name, or volume label syntax.

Direct delivery of the function as a factor, such as L"C:\search\temp\Test.txt", works and retrieving the contents of the notepad one line at a time through fgets(), results in an error as in the above case. That's why fgets() doesn't work the way you want it to because of the way they get the string

I wonder if it is a problem with the process of converting a string to Unicode (? An example of this MD5 hash function was taken from https://docs.microsoft.com/ko-kr/windows/win32/seccrypto/example-c-program--creating-an-md-5-hash-from-file-content and modified accordingly.

c

2022-09-20 14:23

1 Answers

When you read a line from a file with the fgets function, it reads not only one line, but also a new line character ('\n') at the end of the line.

For example, if you have a text file such as the following,

test2.txt
test3.txt

The first value read as fgets is "test2.txt\n". In this state, if you try to open a test2.txt file with this string, it says it is missing because of \n at the end.

On the other hand, since there is no \n after the last line of the above file, test3.txt, the value read in fgets is "test3.txt", in which case you can open the test3.txt file.

Therefore, if you want to read and use the file name with fgets, you can read one line, and if the last column is \n, fill in the column with a null character (0).

Please refer to the code below.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main()
{
    FILE* fp = fopen("test.txt", "r");
    if (fp == NULL) {
        fprintf(stderr, "file opening error 1\n");
        return 1;
    }
    else printf("opened 1\n");

    char buffer[80];
    fgets(buffer, 80, fp);

    FILE* fp2 = fopen(buffer, "r");
    if (fp2 == NULL)
        fprintf(stderr, "file opening error 2\n");
    else
        printf("opened 2\n");

    int file_name_size = strlen(buffer);
    if (buffer[file_name_size - 1] == '\n')
        buffer[file_name_size - 1] = 0;

    FILE* fp3 = fopen(buffer, "r");
    if (fp3 == NULL)
        fprintf(stderr, "file opening error 3\n");
    else
        printf("opened 3\n");

    return 0;
}


2022-09-20 14:23

If you have any answers or tips


© 2022 pinfo. All rights reserved.