这数据类型是中CRC16的计算任何类型的文件更好 [英] Which datatype is better in calculation of CRC16 for any type of file

查看:187
本文介绍了这数据类型是中CRC16的计算任何类型的文件更好的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里使用两个不同的功能用来计算CRC16用于任何类型的文件(.txt文件,压缩.tar,.tar.gz格式,.bin和.SCR,.SH等)和不同尺寸也从 1 KB到5 GB变化

Here i am using two different functions for calculating CRC16 for any type of file (.txt,.tar,.tar.gz,.bin,.scr,.sh etc) and different size also varies from 1 KB to 5 GB.

我要实现这个

   `cross platform 

   less time consuming

   Have to work proper for any type of file and any size`

我得到了这两种功能的CRC值相同。但是任何人能告诉我哪一个更美好计算CRC16与不同的不同的平台上任何规模大小的任何类型的文件。

i got same value of CRC in both functions. but any one can tell me which one is more better to calculate CRC16 for any type of file with any size on different different platform.

在这里,我们要考虑0到255的所有类型的字符。

Here we have to consider 0 to 255 all type characters.

任何机构可以请建议我哪一个是我的要求好。

Can any body please suggest me which one is good in my requirements.

code这两种功能:

Code of both functions :

首先,你已 INT 数据类型在 readChar 在这里我使用 INT readChar

First one which has int datatype in readChar here i am using int readChar

int CRC16_int(const char* filePath) {

    //Declare variable to store CRC result.
    unsigned short result;
    //Declare loop variables.
    int intInnerLoopIndex;
    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.
    int 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) {

        //printf("charcater is %c\n",readChar);
        //printf("charcater is %c and int is %d \n",readChar,readChar);
        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("\nCRC data length in file: %d", chCnt);
    //This is final CRC value for provided message.
    return (result);
}

第二个是 unsigned char型 readChar 的数据类型,在这里我使用 unsigned char型readChar

Second one is unsigned char datatype of readChar Here i am using unsigned char readChar

int CRC16_unchar(const char* filePath) {

    unsigned int filesize;
    //Declare variable to store CRC result.
    unsigned short result;
    //Declare loop variables.
    unsigned int intOuterLoopIndex, intInnerLoopIndex;
    result = 0xffff; //initialize result variable to perform CRC checksum calculation.
    FILE *readFile;
    //Use to read character from file.
    //The problem is if you read a byte from a file with the hex value (for example) 0xfe, 
    //then the char value will be -2 while the unsigned char value will be 254. 
    //This will significantly affect your CRC 
    unsigned 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);
    }
    fseek(readFile, 0, SEEK_END); // seek to end of file
    filesize = ftell(readFile); // get current file pointer
    fseek(readFile, 0, SEEK_SET); // seek back to beginning of file
    /*
     Here reading file and store into variable.
     */
    int chCnt = 0;

    for (intOuterLoopIndex = 0; intOuterLoopIndex < filesize; intOuterLoopIndex++) {
        readChar = getc(readFile);
        printf("charcater is %c and int is %d\n",readChar,readChar);

                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 
                    } else {
                        result = result >> 1; //Perform bit shifting.
                    }
                }
                chCnt++;
    }
    printf("\nCRC data length in file: %d", chCnt);
    return (result);
}

请帮我找出这个问题

感谢

推荐答案

首要的事情。不要做文件读取(或任何来源)和CRC在同一个函数计算。这是糟糕的设计。文件读取通常不是完全独立的平台(虽然POSIX是你最好的朋友),但CRC计算可以独立做得很平台。您可能还需要重复使用其他类型的数据源时未与访问您的fopen CRC算法()

First things first. Don't do file reading (or whatever the source is) and CRC calculating in the same function. This is bad design. File reading is typically not completely platform independent (although POSIX is your best friend), but CRC calculation can be done very platform independently. Also you might want to reuse your CRC algorithm for other kind of data sources which aren't accessed with fopen().

要给你一个提示,CRC校验功能我一直在下降到我的项目有这个原型:

To give you a hint, the CRC function I always drop in to my projects has this prototype:

uint16_t Crc16(const uint8_t* buffer, size_t size, 
                            uint16_t polynomial, uint16_t crc);

您不必一次调用函数和饲料它的文件的完整内容。相反,你可以通过块中的文件循环,并呼吁每个块的功能。你的情况多项式参数是 0xA001异或(这是BTW在逆转的形式多项式)和 CRC 参数设置为 0xFFFF的第一次。你调用函数以后每次你的函数previous返回值传递给 CRC 参数。

You don't have to call the function once and feed it the complete contents of the file. Instead you can loop through the file in blocks and call the function for each block. The polynomial argument in your case is 0xA001 (which is BTW a polynomial in 'reversed' form), and the crc argument is set to 0xFFFF the first time. Each subsequent time you call the function you pass the previous return value of the function to the crc argument.

在你的第二个code frament( CRC16_unchar ),你首先要确定文件大小,然后读取的字节数。不这样做,没有必要限制你处理最高4GB的文件(在大多数情况下)。只是读,直到EOF是清洁恕我直言。

In your second code frament (CRC16_unchar) you first determine the filesize and then read that number of bytes. Don't do that, it unnecessary limits you to handle files of maximum 4GB (in the most cases). Just reading until EOF is cleaner IMHO.

此外,我看到你有符号/无符号字节挣扎。知道,

Furthermore I see that you are struggling with signed/unsigned bytes. Do know that


  • 的printf 不知道,如果你传递一个符号或无符号整数。你告诉的printf 以'%D或%U如何间preT整数。

  • 即使在C本身几乎没有一个有符号和无符号整数之间的差异。 ç不会神奇改变255的值-1,如果你做的中int8_t X = 255

  • printf doesn't know if you pass an signed or unsigned integer. You tell printf with '%d' or '%u' how to interpret the integer.
  • Even in C itself there is hardly a difference between a signed and unsigned integer. C won't magically change the value of 255 to -1 if you do int8_t x = 255.

有关。当C使用一个整数的符号性的更多详细信息请参阅本雁:<一href=\"http://stackoverflow.com/questions/8040005/when-does-the-signedness-of-an-integer-really-matter/8040207#8040207\">When没有一个整数的符号性真的重要吗?。经验法则:只要总是用 uint8_t有处理原始字节

See this anser for more details about when C uses the signedness of an integer: When does the signedness of an integer really matter?. Rule of thumb: Just always use uint8_t for handling raw bytes.

所以,这两种功能都很好关于符号性/整数大小。

So both functions are fine regarding signedness/integer size.

编辑:由于其他用户在他们的回答显示,读取文件块,而不是每字节:

As other users indicated in their answers, read the file in block instead per-byte:

uint16_t CRC16_int(const char* filePath) {
    FILE *readFile;
    const uint8_t buf[1024];
    size_t len;
    uint16_t result = 0xffff;;

    /* Open a file for reading. */
    readFile = fopen(filePath, "rb");
    if (readFile == NULL) {
        exit(1); 
    }

    /* Read until EOF. */
    while ( (len = fread(buf, sizeof(buf), 1, readFile)) > 0 ) {
        result = Crc16(buf, len, 0xA001, result);
    }

    /* readFile could be in error state, check it with ferror() or feof() functions. */

    return result;
}

此外,你应该改变你的函数原型,以使人们有可能返回一个错误,例如:

Also you should alter you function prototype to make it possible to return an error, e.g.:

// Return true when successful, false on error. CRC is stored in result.
bool CRC16_int(const char* filePath, uint16_t *result)

这篇关于这数据类型是中CRC16的计算任何类型的文件更好的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆