php - 具有 poly x^16 + x^10 + x^8 + x^7 + x^3 + 1的php CRC 16 DECT

  显示原文与译文双语对照的内容
112 2

相信我,我试图编码,尝试谷歌,而且没有任何运气。 我正在尝试使用这个 poly 实现一个 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');



请我请任何人帮忙。谢谢。

时间: 原作者:

58 1

定义了一些从高到低的位来处理每个字节的位,一些被定义为处理( 后者通常是描述为的顺序"反射"并使用反向多项式) 。 你的代码将新位放在CRC的LSB端,并向右移动,适合反射 CRC,但CRC-16-DECT似乎是非反射的。

你的" 10100011"输入建议二进制,但被当作 8-byte ASCII字符串处理。

要查看将 10100011当作二进制而不是先从MSB处理时发生的情况,下面是一个手动计算( 输入 8位的输入不需要太多的工作):


polynomial coefficients


 |


 | 10100010 <--- quotient (irrelevant)


 v __________


 10000010110001001 ) 10100011 <-------- input


 ^ 10000010110001001


 -----------------


 = 100001110001001


 ^ 10000010110001001


 -----------------


 = 101110101101


 ^ 10000010110001001


 -----------------


 remainder (CRC) -----> = 111000000101001


 = 0x7029 = 28713



所以把输入当作二进制处理,先做MSB是正确的做法。

下面是执行作业( 因为我不是真正的PHP,最终你想要的是C 代码)的一些C 代码:


#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)


$ 



原作者:
...