各位大侠帮帮忙,有没有8位和16位的CRC算法啊!有源程序也可发[email protected]

解决方案 »

  1.   

    看这个帖子:http://topic.csdn.net/u/20090512/09/554596cc-0fbb-47fa-ac61-fe8f2d2fcdea.html,如果原帖给的算法没错的话,那么就看第14楼我给的C#实现,如果是用来文件的CRC计算,你只要将文件内容读入一个字符串即可。
      

  2.   

    我想要的结果是这样的:
    我输入04990007c08c这字符串,通过CRC校验可以得出结果是 dbad
      

  3.   


    #include <windows.h>
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <math.h>
    #include <string.h>
    #include <stdio.h>
    #include <conio.h> int checkHex( char *str, int len);
    int strToCode8( unsigned char *code, char *str, int len );
    int hex2ToInt(char *p);
    unsigned long CRC_any1 ( unsigned char *blk_adr, unsigned long  blk_len,
       unsigned long ulPoly, unsigned long ulInit, unsigned long ulXorOut, unsigned long ulMask);
    void mK_cRctable(unsigned short gEnpoly);static unsigned long mulInit = 0xffffffff;
    static unsigned long mulXorOut = 0;
    static unsigned long mulMask = 0xffff;
    static unsigned long mulPoly = 0x8005;
    static unsigned long mulTopBit = 0x8000;int main( )
    {
    printf("********  CRC Demo ver1.0  ***********\n");
       unsigned char ID[8] = {0x47, 0x80, 0x2c, 0x01, 0x72, 0x10, 0x88, 0xe7};
       unsigned long CRC;
          printf("Calculates the iPX CRC of an example tag ID\n and and ID entered on the command line\n");
          printf("  usage: crc [[<tagID>] <tagID>...]\n");
          printf("\n  example:\n");
          printf("     crc 47802c01721088e7\n");
       CRC = CRC_any1 ( ID, 6, 0x8005, 0xffff,   0,   0xffff);   printf(" The CRC for      %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x     is ", ID[0], ID[1], ID[2], ID[3], ID[4], ID[5]);
       printf("0x%4.4x\n", CRC);
       
       CRC = CRC_any1 ( ID, 8, 0x8005, 0xffff,   0,   0xffff);   printf(" The CRC check of %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x is ", ID[0], ID[1], ID[2], ID[3], ID[4], ID[5], ID[6], ID[7]);
       printf("0x%4.4x\n", CRC);   return 0;
    }
    unsigned long CRC_any1 ( unsigned char *blk_adr, unsigned long  blk_len,
       unsigned long ulPoly, unsigned long ulInit, unsigned long ulXorOut, unsigned long ulMask)
    {
       unsigned long crc = ulInit;
       unsigned char ucChar;
       int i;
       int iTopBitCRC;
       int iTopBitChar;
       unsigned long ulTopBit;
       if(ulMask > 0xffff)
          ulTopBit = 0x80000000;
       else
          ulTopBit = ((ulMask + 1) >> 1);   while (blk_len--)
       {
          ucChar = *blk_adr;
          for(i=0; i<8; i++)      {
             iTopBitCRC = (crc & ulTopBit) != 0;
             iTopBitChar = (ucChar & 0x80) != 0;
             if(iTopBitCRC != iTopBitChar)
             {
                crc = (crc << 1) ^ ulPoly;
             }
             else
             {
                crc = (crc << 1);
             }
             ucChar <<= 1;
          }
          blk_adr++;
       }
       return (unsigned long)((crc ^ ulXorOut) & ulMask);
    }/*  下面为CRC的计算过程:???????????????
      1.设置CRC寄存器,并给其赋值FFFF(hex)。
      2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
      3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
      4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
      5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
      6.重复第2至第5步直到所有数据全部处理完成。
      7.最终CRC寄存器的内容即为CRC值。
    */
    /***************************************************************************/unsigned long CRC_any ( unsigned char *blk_adr, unsigned long  blk_len)
    {
       unsigned long crc = mulInit;
       unsigned char ucChar;
       int i;
       int iTopBitCRC;
       int iTopBitChar;   while (blk_len--)
       {
          ucChar = *blk_adr;
          for(i=0; i<8; i++)
          {
             iTopBitCRC = (crc & mulTopBit) != 0;
             iTopBitChar = (ucChar & 0x80) != 0;
             if(iTopBitCRC != iTopBitChar)
             {
                crc = (crc << 1) ^ mulPoly + 1;
             }
             else
             {
                crc = (crc << 1);
             }
             ucChar <<= 1;
          }
       }
       return (unsigned long)((crc ^ mulXorOut) & mulMask);
    }
    /***************************************************************************/
    int strToCode8( unsigned char *code, char *str, int len )
    {
       int i;   if(checkHex( str, len) == 0) return 0;
       for(i=0;i<8; i++)
       {
          if( i*2 < len-1)
            code[i] = (unsigned char)(hex2ToInt(&str[i*2]));
          else
             code[i] = 0;
       }
       return 1;
    }int checkHex( char *str, int len)
    {
       for( ;len>0;len--, str++)
       {
          if( *str >= '0' && *str <= '9') continue;
          if( *str >= 'A' && *str <= 'F') continue;
          if( *str >= 'a' && *str <= 'f') continue;
          return 0;
       }
       return 1;
    }int hex2ToInt(char *p)
    {
       char str[3];
       char *q;
       unsigned long v;
       if((p[0] < '0' || p[0] > '9') &&
          (p[0] < 'a' || p[0] > 'f') &&
          (p[0] < 'A' || p[0] > 'F')
          ) return -1;
       if((p[1] < '0' || p[1] > '9') &&
          (p[1] < 'a' || p[1] > 'f') &&
          (p[1] < 'A' || p[1] > 'F') 
          ) return -1;
       strncpy(str, p, 2);
       str[2] =0;
       v = strtoul(str, &q, 16);
       return (int)v;
    }
    /***************************************************************************/
    /*****************************************************************/
    void CRC_setParams(unsigned long ulPoly, unsigned long ulInit, unsigned long ulXorOut, unsigned long ulMask)
    {
       mulPoly = ulPoly;
       mulInit = ulInit;
       mulXorOut = ulXorOut;
       mulMask = ulMask;
       if(mulMask > 0xffff)
          mulTopBit = 0x80000000;
       else
          mulTopBit = ((ulMask + 1) >> 1);
    }
    /***************************************************************************/// Calculate any CRC given the buffer of data bytes, length, the polynomial to use
    // and the other CRC parameters
          //           Poly     Init  XorOut   Mask
          // iPX      0x8005, 0xffff,    0,   0xffff
          // CCITT    0x1021, 0xffff,    0,   0xffff
    //
    // e.g.
    //       ulCRC_CCITT = CRC_any1 ( auchrCode, 6,
    //          0x1021, 0xffff, 0, 0xffff);
    /*
    unsigned short GetCrc_16(unsigned char * pData, int nLength)
    //函数功能:计算数据流* pData的16位CRC校验码,数据流长度为nLength
    {
        unsigned short cRc_16 = 0x0000;    // 初始化
       
        while(nLength>0)
        {
            cRc_16 = (cRc_16 << 8) ^ cRctable_16[((cRc_16>>8) ^ *pData) & 0xff]; //cRctable_16表由函数mK_cRctable生成
            nLength--;
            pData++;
        }
       
        return cRc_16;   
    }
    void mK_cRctable(unsigned short gEnpoly)
    //函数功能:生成0-255对应的16CRC校验码,其实就是计算机算法1(比特型算法)
    //gEnpoly为生成多项式
    //注意,低位先传送时,生成多项式应反转(低位与高位互换)。如CRC16-CCITT为0x1021,反转后为0x8408
    {
    unsigned short cRc_16=0;
    unsigned short i,j,k;for(i=0,k=0;i<256;i++,k++)
    {
          cRc_16 = i<<8;
          for(j=8;j>0;j--)
          {
    if(cRc_16&0x8000)                 //反转时cRc_16&0x0001
                 cRc_16=(cRc_16<<=1)^gEnpoly; //反转时cRc_16=(cRc_16>>=1)^gEnpoly
             else
                 cRc_16<<=1;                   //反转时cRc_16>>=1
          }
          cRctable_16[k] = cRc_16;
    }
    }  */
    这是厂家 给的一个C++源代码,能不能帮我转成C#格式 的:
    要的需求就是,我输入04990007c08c这字符串,通过CRC校验可以得出结果是 dbad
      

  4.   

    看来这个算法被调整过,CRC_any应该是原来的算法,而修改后的是CRC_any1,难怪计算的结果会有差异。
      

  5.   

    奇怪,我怎么输入04990007c08c就是不能返回dbad,虽然是照着上面改写的,按理说应该没错才对,也不知道你那个要求的返回值是从哪里得出的,貌似单单那个主程序的测试是出不来那个结果的,而且下面一大堆函数居然都没用到,非常奇怪。
      

  6.   

    总算搞定了,这个是特殊要求的CRC,输入的就是一组16进制字符而不是一般字符。using System;
    using System.Text;namespace ConsoleApplication1
    {
        class Class1
        {
            static ulong CRC_any1(String blk_adr, ulong ulPoly, ulong ulInit, ulong ulXorOut, ulong ulMask)
            {
                ulong crc = ulInit;
                char ucChar;
                int blk_len = blk_adr.Length;
                int i;
                bool iTopBitCRC;
                bool iTopBitChar;
                ulong ulTopBit;
                if (ulMask > 0xffff)
                    ulTopBit = 0x80000000;
                else
                    ulTopBit = ((ulMask + 1) >> 1);            for (int j = 0; j < blk_len; j++)
                {
                    ucChar = blk_adr[j];
                    for (i = 0; i < 8; i++)
                    {
                        iTopBitCRC = (crc & ulTopBit) != 0;
                        iTopBitChar = (ucChar & 0x80) != 0;
                        if (iTopBitCRC != iTopBitChar)
                        {
                            crc = (crc << 1) ^ ulPoly;
                        }
                        else
                        {
                            crc = (crc << 1);
                        }
                        ucChar <<= 1;
                    }
                }
                return (ulong)((crc ^ ulXorOut) & ulMask);
            }        static String stringConvert(string input)
            {
                StringBuilder tmp = new StringBuilder();
                int length = input.Length;
                if (length % 2 == 0)
                {
                    for (int i = 0; i < length / 2; i++)
                    {
                        tmp.Append(Convert.ToChar(Convert.ToByte(input.Substring(i * 2, 2), 16)));
                    }
                }
                return tmp.ToString();
            }        static void Main(string[] args)
            {
                while (true)
                {
                    Console.WriteLine("请输入需要计算CRC的一串字符,按回车确定。");
                    String tmp = Console.ReadLine();
                    Console.WriteLine(CRC_any1(stringConvert(tmp), 0x8005, 0xffff, 0, 0xffff).ToString("X"));
                }
            }
        }
    }
      

  7.   

    楼主 我现在要写一个CRC校验  要求如下:和你的要求有点差异
    CRC码的计算方法是: 1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
    2.把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低
       8位相异或,把结果放于CRC寄存器;
    3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
    4.如果移出位为0:重复第3步(再次右移一位);
    如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
    5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
    6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
    7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低
       字节进行交换;
    8.最后得到的CRC寄存器内容即为:CRC码。你能否在你的C#代码上少动改动,我要的结果是 输入780000020000 得出结果是 ABA3 谢谢!