Php CRC 16-带多边形x^16和#x2B的DECT;x^10+;x^8+;x^7+;x^3+;1.

Php CRC 16-带多边形x^16和#x2B的DECT;x^10+;x^8+;x^7+;x^3+;1.,php,c,crc16,Php,C,Crc16,相信我,我试过编写代码,试过谷歌,但没有任何运气。 我正试图用这个多边形实现一个CRC16 x^16 + x^10 + x^8 + x^7 + x^3 + 1 使用C语言。因为我更了解PHP,所以我试图让函数运行起来,但我没有得到28713的正确答案。此代码正在生成32713的CRC function crc16($string,$crc=0) { for ( $x=0; $x<strlen( $string ); $x++ ) { $crc = $crc ^ ord( $s

相信我,我试过编写代码,试过谷歌,但没有任何运气。 我正试图用这个多边形实现一个CRC16

x^16 + x^10 + x^8 + x^7 + x^3 + 1
使用C语言。因为我更了解PHP,所以我试图让函数运行起来,但我没有得到28713的正确答案。此代码正在生成32713的CRC

function crc16($string,$crc=0) {

for ( $x=0; $x<strlen( $string ); $x++ ) {

    $crc = $crc ^ ord( $string[$x] );
    echo $crc.'<br />';
    for ($y = 0; $y < 8 ; $y++) {

        if ( ($crc & 0x0001) == 0x0001 ) $crc = ( ($crc >> 1 ) ^ 0x10589  );
        else                             $crc =    $crc >> 1;
    }
}

    return $crc;
}


echo 'CRC:'.crc16('10100011');
函数crc16($string,$crc=0){
对于($x=0;$x>1)^0x10589);
else$crc=$crc>>1;
}
}
返回$crc;
}
回声“CRC:”.crc16('10100011');

请大家帮忙……提前谢谢。

尝试将0x10589更改为0xA001:

function crc16($string,$crc=0) {

    for ( $x=0; $x<strlen( $string ); $x++ ) {

        $crc = $crc ^ ord( $string[$x] );
        for ($y = 0; $y < 8; $y++) {

            if ( ($crc & 0x0001) == 0x0001 ) $crc = ( ($crc >> 1 ) ^ 0xA001 );
            else                             $crc =    $crc >> 1;
        }
    }

    return $crc;
}
函数crc16($string,$crc=0){
对于($x=0;$x>1)^0xA001);
else$crc=$crc>>1;
}
}
返回$crc;
}
  • 有些CRC被定义为处理从MSB到LSB的每个字节的位,有些CRC被定义为处理从LSB到MSB的位(后者通常是被描述为“反射”的顺序,并使用反向多项式)。您的代码将新位放入CRC的LSB端并右移,这适用于反射CRC,但CRC-16-DECT似乎是非反射CRC之一

  • 您输入的“10100011”表示二进制,但被处理为8字节ASCII字符串

  • 要了解将10100011作为二进制处理,并首先从MSB开始工作时会发生什么情况,这里有一个手动计算(因为8位输入不需要太多工作):


    这段代码每次都有效,但我并不完全理解到底发生了什么

      char *MakeCRC(char *BitString)
       {
      static char Res[17];                                 // CRC Result
      char CRC[16];
        int  i;
      char DoInvert;
    
       for (i=0; i<16; ++i)  CRC[i] = 0;                    // Init before calculation
    
       for (i=0; i<strlen(BitString); ++i)
        {
       DoInvert = ('1'==BitString[i]) ^ CRC[15];         // XOR required?
    
      CRC[15] = CRC[14];
      CRC[14] = CRC[13];
      CRC[13] = CRC[12];
      CRC[12] = CRC[11];
      CRC[11] = CRC[10];
      CRC[10] = CRC[9] ^ DoInvert;
      CRC[9] = CRC[8]; 
      CRC[8] = CRC[7] ^ DoInvert;
      CRC[7] = CRC[6] ^ DoInvert;
      CRC[6] = CRC[5];
      CRC[5] = CRC[4];
      CRC[4] = CRC[3];
      CRC[3] = CRC[2] ^ DoInvert;
      CRC[2] = CRC[1];
      CRC[1] = CRC[0];
      CRC[0] = DoInvert;
      }
    
      for (i=0; i<16; ++i)  Res[15-i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
      Res[16] = 0;                                         // Set string terminator
    
        return(Res);
        }
    
    
         // A simple test driver:
    
        #include <stdio.h>
    
       int main()
        {
        char *Data, *Result;                                       // Declare two strings
    
        Data = "1101000101000111";
        Result = MakeCRC(Data);                                    // Calculate CRC
    
        printf("CRC of [%s] is [%s] with P=[10000010110001001]\n", Data, Result);
    
         return(0);
          }
    
    char*MakeCRC(char*BitString)
    {
    静态字符Res[17];//CRC结果
    char-CRC[16];
    int i;
    char-DoInvert;
    
    对于(i=0;它返回的CRC为46445…这不是反向多边形吗?第一个最重要的位等于0x0589,而不是0x10589。但我仍然得到了错误的答案。Matthew,伙计。我欠你一杯酒。非常好用,非常感谢bud,这澄清了我关于CRC的许多问题。比方说,我不知道数据的大小,而不是8位,我得到16位…0xA4321。我不确定我是否理解你的意思。
    crc16()
    获取一个指向字节缓冲区的指针,长度以字节为单位-因此,如果需要16位以上的CRC(0xA4321是20位!),请传入一个2字节缓冲区,长度为2。(在我的示例中,我使用了
    sizeof(in)
    自动计算数组的长度,因此您可以将
    {0xa3}
    更改为
    {0xa3,0x21}
    或其他任何内容。)输入文件将包含这样的数据,0123456789ABCEDF。我需要能够将其分解并传递…感谢您花时间帮我完成这项工作。您的代码就像您所说的那样工作。我的问题是c不像php那样动态,例如,我需要将像“0123456789ABCDEF”这样的字符串转换为in[]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCE,0xDF};
    #include <stdio.h>
    #include <stdint.h>
    
    static uint16_t crc16(const uint8_t *data, size_t len)
    {
        size_t i, j;
        uint16_t crc = 0;
    
        for (i = 0; i < len; i++) {
            crc ^= (data[i] << 8);              /* data at top end, not bottom */
            for (j = 0; j < 8; j++) {
                if ((crc & 0x8000) == 0x8000)   /* top bit, not bottom */
                    crc = (crc << 1) ^ 0x0589;  /* shift left, not right */
                else
                    crc <<= 1;                  /* shift left, not right */
            }
        }
    
        return crc;
    }
    
    int main(void)
    {
        const uint8_t in[] = { 0xa3 };          /* = 10100011 in binary */
        uint16_t crc = crc16(in, sizeof(in));
    
        printf("%u (0x%x)\n", crc, crc);
        return 0;
    }
    
    $ gcc -Wall -o crc16 crc16.c
    $ ./crc16  
    28713 (0x7029)
    $ 
    
      char *MakeCRC(char *BitString)
       {
      static char Res[17];                                 // CRC Result
      char CRC[16];
        int  i;
      char DoInvert;
    
       for (i=0; i<16; ++i)  CRC[i] = 0;                    // Init before calculation
    
       for (i=0; i<strlen(BitString); ++i)
        {
       DoInvert = ('1'==BitString[i]) ^ CRC[15];         // XOR required?
    
      CRC[15] = CRC[14];
      CRC[14] = CRC[13];
      CRC[13] = CRC[12];
      CRC[12] = CRC[11];
      CRC[11] = CRC[10];
      CRC[10] = CRC[9] ^ DoInvert;
      CRC[9] = CRC[8]; 
      CRC[8] = CRC[7] ^ DoInvert;
      CRC[7] = CRC[6] ^ DoInvert;
      CRC[6] = CRC[5];
      CRC[5] = CRC[4];
      CRC[4] = CRC[3];
      CRC[3] = CRC[2] ^ DoInvert;
      CRC[2] = CRC[1];
      CRC[1] = CRC[0];
      CRC[0] = DoInvert;
      }
    
      for (i=0; i<16; ++i)  Res[15-i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
      Res[16] = 0;                                         // Set string terminator
    
        return(Res);
        }
    
    
         // A simple test driver:
    
        #include <stdio.h>
    
       int main()
        {
        char *Data, *Result;                                       // Declare two strings
    
        Data = "1101000101000111";
        Result = MakeCRC(Data);                                    // Calculate CRC
    
        printf("CRC of [%s] is [%s] with P=[10000010110001001]\n", Data, Result);
    
         return(0);
          }