C++ 如何将表驱动的CRC实现转换为按位实现?

C++ 如何将表驱动的CRC实现转换为按位实现?,c++,crc,C++,Crc,我有一些CRC方法需要测试。这些方法不是我自己写的。我能看到的最好的方法是使用不同的技术实现CRC算法,然后比较结果 目前,所有CRC例程都是以表驱动格式编写的。我似乎找不到任何教程来解释如何将代码转换为按位实现。我确信这是我对CRC如何工作缺乏了解 如果有人能提供一个相同的CRC例程以两种不同的方式实现的例子,那就太好了。我在互联网上搜索过,没有找到多少对我的问题有帮助的东西 下面是我需要测试的CRC算法之一的示例代码: // This table implements the EPO CRC

我有一些CRC方法需要测试。这些方法不是我自己写的。我能看到的最好的方法是使用不同的技术实现CRC算法,然后比较结果

目前,所有CRC例程都是以表驱动格式编写的。我似乎找不到任何教程来解释如何将代码转换为按位实现。我确信这是我对CRC如何工作缺乏了解

如果有人能提供一个相同的CRC例程以两种不同的方式实现的例子,那就太好了。我在互联网上搜索过,没有找到多少对我的问题有帮助的东西

下面是我需要测试的CRC算法之一的示例代码:

// This table implements the EPO CRC16 algorithm with a polynomial of 0x17531
static const uint16 s_EPOCRC16Table[] =
{
   0x0000U, 0x7531U, 0xEA62U, 0x9F53U, 0xA1F5U, 0xD4C4U, 0x4B97U, 0x3EA6U,
   0x36DBU, 0x43EAU, 0xDCB9U, 0xA988U, 0x972EU, 0xE21FU, 0x7D4CU, 0x087DU,
   0x6DB6U, 0x1887U, 0x87D4U, 0xF2E5U, 0xCC43U, 0xB972U, 0x2621U, 0x5310U,
   0x5B6DU, 0x2E5CU, 0xB10FU, 0xC43EU, 0xFA98U, 0x8FA9U, 0x10FAU, 0x65CBU,
   0xDB6CU, 0xAE5DU, 0x310EU, 0x443FU, 0x7A99U, 0x0FA8U, 0x90FBU, 0xE5CAU,
   0xEDB7U, 0x9886U, 0x07D5U, 0x72E4U, 0x4C42U, 0x3973U, 0xA620U, 0xD311U,
   0xB6DAU, 0xC3EBU, 0x5CB8U, 0x2989U, 0x172FU, 0x621EU, 0xFD4DU, 0x887CU,
   0x8001U, 0xF530U, 0x6A63U, 0x1F52U, 0x21F4U, 0x54C5U, 0xCB96U, 0xBEA7U,
   0xC3E9U, 0xB6D8U, 0x298BU, 0x5CBAU, 0x621CU, 0x172DU, 0x887EU, 0xFD4FU,
   0xF532U, 0x8003U, 0x1F50U, 0x6A61U, 0x54C7U, 0x21F6U, 0xBEA5U, 0xCB94U,
   0xAE5FU, 0xDB6EU, 0x443DU, 0x310CU, 0x0FAAU, 0x7A9BU, 0xE5C8U, 0x90F9U,
   0x9884U, 0xEDB5U, 0x72E6U, 0x07D7U, 0x3971U, 0x4C40U, 0xD313U, 0xA622U,
   0x1885U, 0x6DB4U, 0xF2E7U, 0x87D6U, 0xB970U, 0xCC41U, 0x5312U, 0x2623U,
   0x2E5EU, 0x5B6FU, 0xC43CU, 0xB10DU, 0x8FABU, 0xFA9AU, 0x65C9U, 0x10F8U,
   0x7533U, 0x0002U, 0x9F51U, 0xEA60U, 0xD4C6U, 0xA1F7U, 0x3EA4U, 0x4B95U,
   0x43E8U, 0x36D9U, 0xA98AU, 0xDCBBU, 0xE21DU, 0x972CU, 0x087FU, 0x7D4EU,
   0xF2E3U, 0x87D2U, 0x1881U, 0x6DB0U, 0x5316U, 0x2627U, 0xB974U, 0xCC45U,
   0xC438U, 0xB109U, 0x2E5AU, 0x5B6BU, 0x65CDU, 0x10FCU, 0x8FAFU, 0xFA9EU,
   0x9F55U, 0xEA64U, 0x7537U, 0x0006U, 0x3EA0U, 0x4B91U, 0xD4C2U, 0xA1F3U,
   0xA98EU, 0xDCBFU, 0x43ECU, 0x36DDU, 0x087BU, 0x7D4AU, 0xE219U, 0x9728U,
   0x298FU, 0x5CBEU, 0xC3EDU, 0xB6DCU, 0x887AU, 0xFD4BU, 0x6218U, 0x1729U,
   0x1F54U, 0x6A65U, 0xF536U, 0x8007U, 0xBEA1U, 0xCB90U, 0x54C3U, 0x21F2U,
   0x4439U, 0x3108U, 0xAE5BU, 0xDB6AU, 0xE5CCU, 0x90FDU, 0x0FAEU, 0x7A9FU,
   0x72E2U, 0x07D3U, 0x9880U, 0xEDB1U, 0xD317U, 0xA626U, 0x3975U, 0x4C44U,
   0x310AU, 0x443BU, 0xDB68U, 0xAE59U, 0x90FFU, 0xE5CEU, 0x7A9DU, 0x0FACU,
   0x07D1U, 0x72E0U, 0xEDB3U, 0x9882U, 0xA624U, 0xD315U, 0x4C46U, 0x3977U,
   0x5CBCU, 0x298DU, 0xB6DEU, 0xC3EFU, 0xFD49U, 0x8878U, 0x172BU, 0x621AU,
   0x6A67U, 0x1F56U, 0x8005U, 0xF534U, 0xCB92U, 0xBEA3U, 0x21F0U, 0x54C1U,
   0xEA66U, 0x9F57U, 0x0004U, 0x7535U, 0x4B93U, 0x3EA2U, 0xA1F1U, 0xD4C0U,
   0xDCBDU, 0xA98CU, 0x36DFU, 0x43EEU, 0x7D48U, 0x0879U, 0x972AU, 0xE21BU,
   0x87D0U, 0xF2E1U, 0x6DB2U, 0x1883U, 0x2625U, 0x5314U, 0xCC47U, 0xB976U,
   0xB10BU, 0xC43AU, 0x5B69U, 0x2E58U, 0x10FEU, 0x65CFU, 0xFA9CU, 0x8FADU,
};

/**
 * This routine returns the CRC-16 of Cp_ptr.
 * This CRC routine is reversed to match the routine used in the EPO.
 *
 * @param  const uint8 *Cp_ptr - data pointer to the bit string to be calculated over
 * @param  const uint32 Len    - the number of bytes pointed to by Cp_ptr
 * @return the calculated 16-bit CRC
 * @ureq
 *    -# epoCRC16() shall calculate a 16-bit CRC on a block of data starting at an address of a specified length.
 *    -# epoCRC16() shall ASSERT if the passed in pointer is NULL.
 */
uint16 epoCRC16( const uint8 *Cp_ptr, const uint32 Len )
{
   ASSERT( Cp_ptr != NULL );

   // local variable
   uint16 crc = 0x0;

   // calculate the crc
   for ( uint16 i = Len; i > 0; i-- )
   {
      const uint8 TableIndex = ( *Cp_ptr ^ static_cast<uint8>( crc >> 8 ) );
      crc = static_cast<uint16>( crc << 8 );
      crc = ( crc ^ s_EPOCRC16Table[TableIndex] );
      Cp_ptr++;
   }

   return crc;
}
//此表使用多项式0x17531实现EPO CRC16算法
静态常数uint16 s_EPOC16表[]=
{
0x0000U、0x7531U、0xEA62U、0x9F53U、0xA1F5U、0xD4C4U、0x4B97U、0x3EA6U、,
0x36DBU、0x43EAU、0xDCB9U、0xA988U、0x972EU、0xE21FU、0x7D4CU、0x087DU、,
0x6DB6U、0x1887U、0x87D4U、0xF2E5U、0xCC43U、0xB972U、0x2621U、0x5310U、,
0x5B6DU、0x2E5CU、0xB10FU、0xC43EU、0xFA98U、0x8FA9U、0x10FAU、0x65CBU、,
0xDB6CU、0xAE5DU、0x310EU、0x443FU、0x7A99U、0x0FA8U、0x90FBU、0xE5CAU、,
0xEDB7U、0x9886U、0x07D5U、0x72E4U、0x4C42U、0x3973U、0xA620U、0xD311U、,
0xB6DAU、0xC3EBU、0x5CB8U、0x2989U、0x172FU、0x621EU、0xFD4DU、0x887CU、,
0x8001U、0xF530U、0x6A63U、0x1F52U、0x21F4U、0x54C5U、0xCB96U、0xBEA7U、,
0xC3E9U、0xB6D8U、0x298BU、0x5CBAU、0x621CU、0x172DU、0x887EU、0xFD4FU、,
0xF532U、0x8003U、0x1F50U、0x6A61U、0x54C7U、0x21F6U、0xBEA5U、0xCB94U、,
0xAE5FU、0xDB6EU、0x443DU、0x310CU、0x0FAAU、0x7A9BU、0xE5C8U、0x90F9U、,
0x9884U、0xEDB5U、0x72E6U、0x07D7U、0x3971U、0x4C40U、0xD313U、0xA622U、,
0x1885U、0x6DB4U、0xF2E7U、0x87D6U、0xB970U、0xCC41U、0x5312U、0x2623U、,
0x2E5EU、0x5B6FU、0xC43CU、0xB10DU、0x8FABU、0xFA9AU、0x65C9U、0x10F8U、,
0x7533U、0x0002U、0x9F51U、0xEA60U、0xD4C6U、0xA1F7U、0x3EA4U、0x4B95U、,
0x43E8U、0x36D9U、0xA98AU、0xDCBBU、0xE21DU、0x972CU、0x087FU、0x7D4EU、,
0xF2E3U、0x87D2U、0x1881U、0x6DB0U、0x5316U、0x2627U、0xB974U、0xCC45U、,
0xC438U、0xB109U、0x2E5AU、0x5B6BU、0x65CDU、0x10FCU、0x8FAFU、0xFA9EU、,
0x9F55U、0xEA64U、0x7537U、0x0006U、0x3EA0U、0x4B91U、0xD4C2U、0xA1F3U、,
0xA98EU、0xDCBFU、0x43ECU、0x36DDU、0x087BU、0x7D4AU、0xE219U、0x9728U、,
0x298FU、0x5CBEU、0xC3EDU、0xB6DCU、0x887AU、0xFD4BU、0x6218U、0x1729U、,
0x1F54U、0x6A65U、0xF536U、0x8007U、0xBEA1U、0xCB90U、0x54C3U、0x21F2U、,
0x4439U、0x3108U、0xAE5BU、0xDB6AU、0xE5CCU、0x90FDU、0x0FAEU、0x7A9FU、,
0x72E2U、0x07D3U、0x9880U、0xEDB1U、0xD317U、0xA626U、0x3975U、0x4C44U、,
0x310AU、0x443BU、0xDB68U、0xAE59U、0x90FFU、0xE5CEU、0x7A9DU、0x0FACU、,
0x07D1U、0x72E0U、0xEDB3U、0x9882U、0xA624U、0xD315U、0x4C46U、0x3977U、,
0x5CBCU、0x298DU、0xB6DEU、0xC3EFU、0xFD49U、0x8878U、0x172BU、0x621AU、,
0x6A67U、0x1F56U、0x8005U、0xF534U、0xCB92U、0xBEA3U、0x21F0U、0x54C1U、,
0xEA66U、0x9F57U、0x0004U、0x7535U、0x4B93U、0x3EA2U、0xA1F1U、0xD4C0U、,
0xDCBDU、0xA98CU、0x36DFU、0x43EEU、0x7D48U、0x0879U、0x972U、0xE21BU、,
0x87D0U、0xF2E1U、0x6DB2U、0x1883U、0x2625U、0x5314U、0xCC47U、0xB976U、,
0xB10BU、0xC43AU、0x5B69U、0x2E58U、0x10FEU、0x65CFU、0xFA9CU、0x8FADU、,
};
/**
*此例程返回Cp_ptr的CRC-16。
*该CRC例程被反转以匹配EPO中使用的例程。
*
*@param const uint8*Cp_ptr-指向要计算的位字符串的数据指针
*@param const uint32 Len-Cp_ptr指向的字节数
*@返回计算出的16位CRC
*@ureq
*-#epoCRC16()应计算从指定长度地址开始的数据块上的16位CRC。
*-#epoCRC16()应断言传入的指针是否为NULL。
*/
uint16 epoCRC16(常数uint8*Cp\U ptr,常数uint32 Len)
{
断言(Cp_ptr!=NULL);
//局部变量
uint16 crc=0x0;
//计算crc
对于(uint16 i=Len;i>0;i--)
{
const uint8 TableIndex=(*Cp_ptr^static_cast(crc>>8));

crc=静态_转换(crc您首先需要crc多项式,根据crc的位顺序,您可以在该表的第二项或第128项中找到它。或者在这种情况下,您可以在注释中找到它,
0x17531
x
后面的
1
是多项式的第一项,它只是定义了tCRC的长度。它在计算中被删除。您可以在表的第二个条目中找到
0x7531

此例程(在C中)仅使用多项式生成上表:

void make_crc_table(unsigned poly, unsigned *table)
{
    unsigned n, k, crc;

    for (n = 0; n < 256; n++) {
        crc = n << 8;
        for (k = 0; k < 8; k++)
            crc = crc & 0x8000 ? (crc << 1) ^ poly : crc << 1;
        table[n] = crc & 0xffff;
    }
}
对于一个工具,请检查,它有一个用于任意CRC的代码生成器

有关CRC计算的说明,请参见。

//可以通过以下多项式0x17531的源代码来比较Bitise和表级CRC-16!
//CRC.cpp:
//
#包括“stdafx.h”
#包括“CRC.h”
#包括“afx.h”
#包括
#ifdef_调试
#定义新调试\u新
#恩迪夫
CWinApp-theApp;
使用名称空间std;
#定义BUFLENGTH(0x100000*1)//0x100000=1MB
void makeCRC16Table();
无效CRC16更新(无符号短代码和crc0,常量无效*数据,整数长度);
无效crc16updateBitwise(无符号短字符和crc0,常量无效*数据,整数长度);
静态字节CRC8表[256];
静态无符号短CRC16表[256];
静态无符号长CRC32表[256];
int_tmain(int-argc,TCHAR*argv[],TCHAR*envp[]
{
int nRetCode=0;
无符号字符crc8=0x00;
无符号短crc16=0x0000;
无符号长crc32=0x00000000;
byte*dataBuf=新字节[BUFLENGTH];
if(dataBuf==0)
{

我想我从来没有见过有人真正使用CRC16。现在都是CRC32。我不同意你的测试方法。测试这种算法的最好方法是输入你知道答案的输入,并确保它产生正确的值。Anon-Mail:理论上这是可行的。我没有
unsigned epobit(unsigned char *buf, unsigned len, unsigned poly)
{
    unsigned n, k, crc = 0;

    for (n = len; n > 0; n--) {
        crc ^= (*buf++ << 8);
        for (k = 0; k < 8; k++)
            crc = crc & 0x8000 ? (crc << 1) ^ poly : crc << 1;
    }
    return crc & 0xffff;
}
// Bitise and tablewise CRC-16 can be compared by following source code with polynomial 0x17531 !

// CRC.cpp : 
//

#include "stdafx.h"
#include "CRC.h"

#include "afx.h"
#include <conio.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CWinApp theApp;

using namespace std;

#define BUFLENGTH (0x100000*1)  //0x100000=1MB

void makeCRC16Table();
void crc16update(unsigned short &crc0, const void *data, int length);
void crc16updateBitwise(unsigned short &crc0, const void *data, int length);

static byte crc8Table[256];
static unsigned short crc16Table[256];
static unsigned long crc32Table[256];

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    unsigned char crc8=0x00;
    unsigned short crc16=0x0000;
    unsigned long crc32=0x00000000;

    byte *dataBuf = new byte[BUFLENGTH];
    if(dataBuf==0)
    {
        cout<<"Not enough memory allocation to dataBuf[] !";
        while(!_kbhit());
        return nRetCode;
    }
    for(int i=0; i<BUFLENGTH; i++)
        dataBuf[i]=i+1;

    makeCRC16Table();
    crc16=0x00;
    crc16update(crc16, dataBuf, BUFLENGTH);
    crc16=0x00;
    crc16updateBitwise(crc16, dataBuf, BUFLENGTH);

    delete[] dataBuf;

    while(!_kbhit());

    }

    return nRetCode;
}

void makeCRC16Table()
{
    /* generate a table for a byte-wise 16-bit CRC caculation on the polynomial ;
      */
    CString soutputfile=_T("crc16Table.txt");
    CString soutputbuffer;
    CStdioFile fileTarget( soutputfile, CFile::modeCreate | CFile::modeWrite );
    int i,j;
    unsigned long poly, cc;
    /* terms of polynomial defining this crc (except x^16) */
    //static const byte pp[]={0,5,12};
    static const byte pp[]={0,2,15};

    /* make exclusive-or pattern from polynomial 0x1021 */
    poly=0;
    //for(i=0; i<sizeof(pp)/sizeof(byte); i++) 
    //  poly|=1<<pp[i];
    poly=0x7531;
    //poly=0x1021;
    //poly=0x8005;

    for(i=0; i<256; i++) {
        cc=i<<8; 
        for(j=0; j<8; j++) {
            cc=(cc&0x8000)?(poly^(cc<<1)):(cc<<1);  //MSB first transmission

        }
        crc16Table[i]=cc&0xffff;

        soutputbuffer.Format("%3d:%04X\n", i, crc16Table[i]);
        fileTarget.WriteString(soutputbuffer);
    }
    fileTarget.Close();
    //ShellExecute(NULL, NULL, soutputfile, NULL, NULL, SW_SHOWNORMAL);
}

void crc16update(unsigned short &crc0, const void *data, int length)
{
    CString soutputfile=_T("crc16.txt");
    cout<<"\n"<<soutputfile<<"\n";

    CString soutputbuffer, soutputbufferTotal;
    CStdioFile fileTarget( soutputfile, CFile::modeCreate | CFile::modeWrite );

    int percentage=0, ntemp;
    unsigned short crc,crc1;
    const unsigned char *buf=(const unsigned char *)data;
    int i=0, j;
    crc=crc0;
    while(i<length) 
    {
        ntemp=i/(length/100);
        if(ntemp!=percentage)
        {
            soutputbuffer.Format("%d%% ", percentage );
            cout<<soutputbuffer;
            percentage=ntemp;
            if(ntemp<0)
                int nn=0;
        }

        crc1=crc;
        j = ((crc >> 8) ^ buf[i]) & 0xff;
        crc = (crc << 8) ^ crc16Table[j];

        soutputbuffer.Format("%d:%02X:%04X>%04X\n", i, buf[i], crc1, crc );
        fileTarget.WriteString(soutputbuffer);
        i++;
    }
    soutputbuffer.Format("\n%04X>%04X", crc1, crc );
    cout<<soutputbuffer;
    crc0=crc;
    fileTarget.Close();
    //ShellExecute(NULL, NULL, soutputfile, NULL, NULL, SW_SHOWNORMAL);
}

void crc16updateBitwise(unsigned short &crc0, const void *data, int length)
{
    CString soutputfile=_T("crc16BW.txt");
    cout<<"\n"<<soutputfile<<"\n";

    CString soutputbuffer;
    CStdioFile fileTarget( soutputfile, CFile::modeCreate | CFile::modeWrite );

    static const byte BitTable[]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
    int percentage=0, ntemp;
    unsigned long poly;
    /* terms of polynomial defining this crc (except x^16) */
    //static const byte pp[]={0,5,12};//CCITT
    static const byte pp[]={0,2,15};//GENERAL

    /* make exclusive-or pattern from polynomial 0x1021 */
    int i;
    poly=0;
    //for(i=0; i<sizeof(pp)/sizeof(byte); i++) 
    //  poly|=1<<pp[i];
    //poly=0x8005;
    poly=0x7531;

    unsigned short crc,crc1;
    const unsigned char *buf=(const unsigned char *)data;
    byte a,b,c;
    crc=crc0;
    i=0;
    while(i<length) 
    {
        ntemp=i/(length/100);
        if(ntemp!=percentage)
        {
            soutputbuffer.Format("%d%% ", percentage );
            cout<<soutputbuffer;
            percentage=ntemp;
        }
        crc1=crc;
        for(int j=0; j<8; j++) {
            a=(crc&0x8000)?1:0;//x^16
            b=(buf[i]&BitTable[7-j])?1:0;////MSB first transmission 
            c=a^b;
            crc=(c?(poly^(crc<<1)):(crc<<1))&0xffff;
        }
        soutputbuffer.Format("%d:%02X:%04X>%04X\n", i, buf[i], crc1&0xffff, crc&0xffff );
        fileTarget.WriteString(soutputbuffer);
        i++;
    }
    soutputbuffer.Format("\n%04X>%04X", crc1&0xffff, crc&0xffff );
    cout<<soutputbuffer;
    crc0=crc;
    fileTarget.Close();
    //ShellExecute(NULL, NULL, soutputfile, NULL, NULL, SW_SHOWNORMAL);
}