-4

I have been asked to create a checksum algorithm for a file transfer, the C++ code I have been given is as follows:

// ChecksumTestTool.cpp : Defines the entry point for the console 
application.
//

#include "stdafx.h"

#include <string>
#include <stdio.h>
#include <iostream>

unsigned long CalculateChecksum(FILE* pFile);

int main(int argc, char *argv[])
{
    int result = 0;
    //Get filename from command args
    std::string fileName;
    if (argc >= 1)
    {
        fileName = argv[0];
        //Open file with read access
        FILE* pFile = nullptr;
        int error = fopen_s(&pFile, fileName.c_str(), "r");
        if (error != 0 || pFile == nullptr)
        {
            printf("Failed to open file with error %d\r\n", error);
            result = -1;
        }
        else
        {
            //Calculate the checksum
            unsigned long checksum = CalculateChecksum(pFile);
            printf("Calculated Checksum for %s is %lu (0x%04X)\r\n", 
            fileName.c_str(), checksum, checksum);
        }
    }
    else
    {
        printf("Must enter filename on command line\r\n");
        result = -1;
    }

    //Wait here so we can see result
    printf("\r\nPress Any Key to Exit\r\n");
    getchar();
    return 0;
}

unsigned long CalculateChecksum(FILE* pFile)
{
unsigned long checksum = 0;
//TODO:: Calculate the checksum
return checksum;
}

I need to create the checksum at the point '//TODO:: Calculate the checksum'. The algorithm need to check whether the file transfers or not. So far I have tried:

unsigned long CalculateChecksum(FILE* pFile)
{
    unsigned long checksum = 0;
    //TODO:: Calculate the checksum
    unsigned long word = 0;
    while (file.read(reinterpret_cast<char*>(&word), sizeof(word))); {
    checksum += word;
    }

    if (file.gcount()); {
        word &= (~0U >> ((sizeof(unsigned long) - file.gcount()) * 8));
        checksum += word;
    }

    return checksum;
}

and I get errors saying 'file' is an undeclared identifier and that left '.gcount' must have class/struct/union

I have searched around for multiple checksums and this algorithm is the only one I found that works within this code

Tay.S
  • 1
  • 1
  • 4
  • 2
    So, what have you tried so far? What exactly has you stuck? – NathanOliver Jul 13 '17 at 12:15
  • 1
    Are you having trouble inventing an algorithm, or implementing it? – aschepler Jul 13 '17 at 12:15
  • Possible duplicate of [How to get the MD5 hash of a file in C++?](https://stackoverflow.com/questions/1220046/how-to-get-the-md5-hash-of-a-file-in-c) – mrogal.ski Jul 13 '17 at 12:16
  • A naive way to do it could b to compute the MD5/shasum/crc32 hash of the file and use that as checksum. – Davide Spataro Jul 13 '17 at 12:17
  • So, what, you just expect (A) someone to write it for you and (B) without them having any idea of what kind of checksum you want? – underscore_d Jul 13 '17 at 12:17
  • Aschepler, I have implemented a algorithm but it does not function properly as it has a few errors – Tay.S Jul 13 '17 at 12:22
  • Then what is the point of posting without telling us that you have tried, what you tried, and what the result was? – underscore_d Jul 13 '17 at 12:24
  • Why would you use "file", when your variable is called pFile? – SinisterMJ Jul 13 '17 at 12:30
  • I changed the '.file' to '.pFile' and the only errors I am receiving is that '.read' and '.gcount' need a class/struct/union infront of them – Tay.S Jul 13 '17 at 12:33
  • Yeah, cause its a pointer to a file. You should try pFile->gcount() instead. – SinisterMJ Jul 13 '17 at 12:34
  • I have changed the '.' to '->' and i am no longer getting the error, however the system states that 'read' and 'gcount' are not members of '_iobuf' – Tay.S Jul 13 '17 at 12:36
  • Use a debugger. You have stupid mistakes here, for example `fileName = argv[0];`: `argv[0]` is the name of the program itself (first *word* in the command line) while the first actual argument is `argv[1]`. – Serge Ballesta Jul 13 '17 at 12:38
  • the argv[0] and argv[1] have no effect on the algorithm, the only problem that is now occuring is that read and gcount are not members of _iobuf – Tay.S Jul 13 '17 at 12:42
  • Yeah, cause they are members of iostream, and not iobuffer. You need to understand what the code does, and implement accordingly. – SinisterMJ Jul 13 '17 at 13:03
  • The last 'checksum' I dealt with was the simple sum of the bytes The inverse(?) of the checksum was simply appended to the byte stream being sent or read or written or received. When the bytes are received, all the bytes, including the check sum, should sum to 0. Fancier checksum forms can identify which byte is wrong. There are many variants. Try wikipedia. – 2785528 Jul 13 '17 at 14:48

1 Answers1

1

Some things: you pass a variable called pFile to the function, within the function you use file.

You use if(expression);, therefore the part after the if will always be executed, as the if() has no influence whatsoever.

I didn't even consider whether the checksum function works, but when you do

if(term);
{
    // Do something
}

the Do something will always be reached. It should rather be

if (term)
{
   // Do something
}

so it will only do it if the term evaluates true

SinisterMJ
  • 3,425
  • 2
  • 33
  • 53
  • I removed the ';'. I had that in the program as it said that it was needed before the '{', although that was because the '{' were on the same line as the if. – Tay.S Jul 13 '17 at 12:47
  • @Tay.S What said the semicolon was needed? It makes no difference whether the braces are on the same line, the next one, or 3 screens away... C/C++ ignore surplus whitespace. – underscore_d Jul 13 '17 at 17:24