问题
Here i want to know the how can i implement calculate CRC16 for Any type of file,
Here i have idea about CRC16 and its code logic.
here i made one function which take file path as a input and find out CRC value of this. here i pass file name in this function and this functions calculates CRC value of this file. but i want to calculate all types of files like .tar,.tar.gz,.txt,.bin,.scr etc
.
so here i open this all files and "rb"
mode and take one by one character and find out CRC value
its right way? may be i missing something in this. its works fine for .txt
and all other files but it will create problems in .tar, .tar.gz
type files. Because here i have one file which is 890 MB
and its name is file.tar.gz
and its take 203
Microseconds and I have other file which is 382 MB
and its name is file2.tar
its take 6097850.000000 Microseconds
its unbelievable for me hows its possible?
My question are these
1 Some thing problem in my CRC code ?
2 Problem in reading file data style, may be i am reading file data in wrong manner for .tar.gz.
Here is my code :
int CRC16(const char* filePath) {
//Declare variable to store CRC result.
unsigned short result;
//Declare loop variables.
int intOuterLoopIndex, intInnerLoopIndex, nLen;
result = 0xffff; //initialize result variable to perform CRC checksum calculation.
//Store message which read from file.
//char content[2000000];
//Create file pointer to open and read file.
FILE *readFile;
//Use to read character from file.
char readChar;
//open a file for Reading
readFile = fopen(filePath, "rb");
//Checking file is able to open or exists.
if (!readFile) {
fputs("Unable to open file %s", stderr);
}
/*
Here reading file and store into variable.
*/
int chCnt = 0;
while ((readChar = getc(readFile)) != EOF) {
result ^= (short) (readChar);
for (intInnerLoopIndex = 0; intInnerLoopIndex < 8; intInnerLoopIndex++) {
if ((result & 0x0001) == 0x0001) {
result = result >> 1; //Perform bit shifting.
result = result ^ 0xa001; //Perform XOR operation on result.
} else {
result = result >> 1; //Perform bit shifting.
}
}
//content[chCnt] = readChar;
chCnt++;
}
printf("CRC data length in file: %d", chCnt);
return (result);
}
回答1:
char readChar;
is wrong, it needs to be int readChar
;
getc() returns an int, so it can signal EOF to you. EOF is likely the value -1
If you convert the return value to a char, and read a byte with the value 255, 255 will be interpreted as -1, and you stop reading at the first byte that has the value 255.
回答2:
This code is wrong in different points:
if (!readFile) {
fputs("Unable to open file %s", stderr);
}
If the file opening fails you don't return but continue! And the puts
is wrong also, you don't specify the file name.
Also, getc()
returns an integer, but you put it in a char and it may end just when it finds an EOF character! Don't ignore compiler warnings...
I would download a small CRC calculator program, so that you can test if your code is working properly.
来源:https://stackoverflow.com/questions/9413009/confusion-in-file-verification-with-crc16-in-c