C算法:WORD gen_crc(BYTE *frame, short frame_len)
{
   BYTE c, treat, bcrc;
   WORD wcrc = 0;
   short i, j;
   for (i = 0; i < frame_len; i++)
   {
      c = frame[i];
      for (j = 0; j < 8; j++)
      {
        treat = c & 0x80;
c <<= 1;
bcrc = (wcrc >> 8) & 0x80;
wcrc <<= 1;
if (treat != bcrc)
   wcrc ^= 0x1021;
       }
   }
    return wcrc;
}
Delphi 算法:function gen_crc(const Buffer: array of Byte; const BufferLength: Smallint): Word; //CRC算法
var
  c,treat, bcrc: Byte;
   wcrc: Word;
i,j: Smallint;
begin
wcrc := 0;
i := 0;
while i < BufferLength do
begin
c := Buffer[i];
for j := 0 to 7 do
begin
treat := c and $80;
c := c shl 1;
bcrc := (wcrc shr 8) and $80;
wcrc := wcrc shl 1;
if treat <> bcrc then
wcrc := wcrc xor $1021;
end;
i := i + 1;
end;
gen_crc := wcrc;
end;以上是c和delphi的crc算法,如是b:array[0..3] of byte=(0,0,0,6);   在delphi中算出是24774,C中47692.上面两个算法是一样的呀,为什么得出两个不同的结果。请教!

解决方案 »

  1.   

    帅哥,看看这个unit   UCRC16;
      //CRC-ITU   (CRC-CCITT)   算法,CRC16算法的一种   
      //校验码生成多项式:g(x)   =   x^16+x^12+x^5+1   
        
      interface   
      type   
          PBYTE   =   ^Byte;         //计算CRC校验码             
          function   GetCrc16(const   pData:Pointer;nLength:Integer):Word;   
        
          //校验函数   
          function   CheckCRC16(const   pData:Pointer;   nLength:   Integer):Boolean;   
        
      implementation   
        
      const   CRCTable16:array[0..255]   of   Word   =   (   
              $0000,   $1189,   $2312,   $329b,   $4624,   $57ad,   $6536,   $74bf,   
              $8c48,   $9dc1,   $af5a,   $bed3,   $ca6c,   $dbe5,   $e97e,   $f8f7,   
              $1081,   $0108,   $3393,   $221a,   $56a5,   $472c,   $75b7,   $643e,   
              $9cc9,   $8d40,   $bfdb,   $ae52,   $daed,   $cb64,   $f9ff,   $e876,   
              $2102,   $308b,   $0210,   $1399,   $6726,   $76af,   $4434,   $55bd,   
              $ad4a,   $bcc3,   $8e58,   $9fd1,   $eb6e,   $fae7,   $c87c,   $d9f5,   
              $3183,   $200a,   $1291,   $0318,   $77a7,   $662e,   $54b5,   $453c,   
              $bdcb,   $ac42,   $9ed9,   $8f50,   $fbef,   $ea66,   $d8fd,   $c974,   
              $4204,   $538d,   $6116,   $709f,   $0420,   $15a9,   $2732,   $36bb,   
              $ce4c,   $dfc5,   $ed5e,   $fcd7,   $8868,   $99e1,   $ab7a,   $baf3,   
              $5285,   $430c,   $7197,   $601e,   $14a1,   $0528,   $37b3,   $263a,   
              $decd,   $cf44,   $fddf,   $ec56,   $98e9,   $8960,   $bbfb,   $aa72,   
              $6306,   $728f,   $4014,   $519d,   $2522,   $34ab,   $0630,   $17b9,   
              $ef4e,   $fec7,   $cc5c,   $ddd5,   $a96a,   $b8e3,   $8a78,   $9bf1,   
              $7387,   $620e,   $5095,   $411c,   $35a3,   $242a,   $16b1,   $0738,   
              $ffcf,   $ee46,   $dcdd,   $cd54,   $b9eb,   $a862,   $9af9,   $8b70,   
              $8408,   $9581,   $a71a,   $b693,   $c22c,   $d3a5,   $e13e,   $f0b7,   
              $0840,   $19c9,   $2b52,   $3adb,   $4e64,   $5fed,   $6d76,   $7cff,   
              $9489,   $8500,   $b79b,   $a612,   $d2ad,   $c324,   $f1bf,   $e036,   
              $18c1,   $0948,   $3bd3,   $2a5a,   $5ee5,   $4f6c,   $7df7,   $6c7e,   
              $a50a,   $b483,   $8618,   $9791,   $e32e,   $f2a7,   $c03c,   $d1b5,   
              $2942,   $38cb,   $0a50,   $1bd9,   $6f66,   $7eef,   $4c74,   $5dfd,   
              $b58b,   $a402,   $9699,   $8710,   $f3af,   $e226,   $d0bd,   $c134,   
              $39c3,   $284a,   $1ad1,   $0b58,   $7fe7,   $6e6e,   $5cf5,   $4d7c,   
              $c60c,   $d785,   $e51e,   $f497,   $8028,   $91a1,   $a33a,   $b2b3,   
              $4a44,   $5bcd,   $6956,   $78df,   $0c60,   $1de9,   $2f72,   $3efb,   
              $d68d,   $c704,   $f59f,   $e416,   $90a9,   $8120,   $b3bb,   $a232,   
              $5ac5,   $4b4c,   $79d7,   $685e,   $1ce1,   $0d68,   $3ff3,   $2e7a,   
              $e70e,   $f687,   $c41c,   $d595,   $a12a,   $b0a3,   $8238,   $93b1,   
              $6b46,   $7acf,   $4854,   $59dd,   $2d62,   $3ceb,   $0e70,   $1ff9,   
              $f78f,   $e606,   $d49d,   $c514,   $b1ab,   $a022,   $92b9,   $8330,   
              $7bc7,   $6a4e,   $58d5,   $495c,   $3de3,   $2c6a,   $1ef1,   $0f78   
      );   
        
        
      function   GetCrc16(const   pData:Pointer;nLength:Integer):Word;   
      var   fcs:Word;   p:PBYTE;   
      begin   
              p   :=   PBYTE(PData);   
              fcs   :=   $ffff;         //   初始化   
              while(nLength>0)   do   
              begin   
                      fcs   :=   (fcs   shr   8)   xor   CRCTable16[(fcs   xor   p^)   and   $ff];   
                      Dec(nLength);   
                      Inc(p);   
              end;   
        
              result   :=   not   fcs;         //   取反   
      end;   
        
        
      function   CheckCRC16(const   pData:Pointer;   nLength:   Integer):Boolean;   
      var   fcs:Word;   p:PBYTE;   
      begin   
          p   :=   PBYTE(pData);   
          fcs   :=   $ffff;         //   初始化   
          while(nLength>0)   do   
          begin   
                  fcs   :=   (fcs   shr   8)   xor   CRCTable16[(fcs   xor   p^)   and   $ff];   
                  Dec(nLength);   
                  Inc(p);   
          end;   
        
          Result:=   (fcs   =   $f0b8);     //   0xf0b8是CRC-ITU的"Magic   Value"   
      end;   
        
      end.
      

  2.   

    C中的结果也是24774哇。楼主是否测试的方法上有问题?以下是我的测试代码:#include "stdafx.h"#define WORD unsigned int
    #define BYTE unsigned shortWORD gen_crc(BYTE *frame, short frame_len)
    {
       BYTE c, treat, bcrc;
       WORD wcrc = 0;
       short i, j;
       for (i = 0; i < frame_len; i++)
       {
          c = frame[i];
          for (j = 0; j < 8; j++)
          {
            treat = c & 0x80;
        c <<= 1;
    bcrc = (wcrc >> 8) & 0x80;
    wcrc <<= 1;
    if (treat != bcrc) wcrc ^= 0x1021;
          }
       }
       return wcrc;
    }int main(int argc, char* argv[])
    {
    BYTE a[4] = {0, 0, 0, 6};
    printf("%d \n", gen_crc(a, 4));
    getchar();
    return 0;
    }
      

  3.   

    Modbus CRC校验算法的描述如下:
    1). 将CRC赋值0xFFFF。
    2). 取初始信息的第一个字节(8位)与CRC进行异或运算,将结果赋给CRC。
    3). 将CRC数据右移一位,最前位(左边)补0。
    4). 如果右移前,CRC最低位(最右端)为1,则将右移后的CRC与0xA001进行异或运算,且将结果赋给CRC。否则,跳过此步。
    5). 重复3,4步8次(即右边8位)。
    6). 对初始信息的下一个字节,同样执行2,3,4,5步,直到信息中所有字节都执行了同样的步骤。7). 将此时得到的CRC值的高8位和低8位交换,加在初始信息末尾即得到完整的传输信息。
    程序如下:
    #include <stdio.h>
    #define uint unsigned int int crc(unsigned char *buf,int start,int cnt) 
    {
    int   i,j;
    unsigned  int  temp,temp2,flag; temp=0xFFFF; for (i=start; i<cnt; i++)
    {
    temp=temp ^ buf[i]; for (j=1; j<=8; j++)
    {
    flag=temp & 0x0001;
    temp=temp >> 1;
    if (flag) temp=temp ^ 0xA001;
    }
    } /* Reverse byte order. */ temp2=temp >> 8;
    temp=(temp << 8) | temp2;
    temp &= 0xFFFF; return(temp);
    }int main()
    {
    int temp;
    unsigned char ibuf[7]={1,4,4,66,8,204,205};
    int i;
    /*
    for(i=0;i<6;i++)
    {
    printf("input number:");
    scanf("%d",&ibuf[i]);
    }
    */
    for(i=0;i<7;i++)
    printf("buf=%d ,",ibuf[i]);
    ibuf[i] &= 0xff;
    temp = crc(ibuf,0,7);
    //temp &=0xff00;
    printf("crc=%2x\n",temp);
    return 0;}