简介
Cyclic Redundancy Check循环冗余检验,是基于数据计算一组效验码,用于核对数据传输过程中是否被更改或传输错误。
计算流程
预置1个16位的寄存器为十六进制
0xFFFF
;称此寄存器为CRC寄存器
实现代码:
$crc = 0xFFFF;
把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的
CRC寄存器
的低8位相异或,结果放入CRC寄存器
中
实现代码:
$crc=($crc>>8) ^ ord($str[$i]);
把CRC寄存器的内容右移一位(朝低位)用0填补,并检查右移后的移除位
实现代码:
($crc & 0x0001) == 0
如果移出位为0:重复第3步(再次右移一位);如果移出位为1:
CRC寄存器
与0xA001
进行异或
实现代码:
if (($crc & 0x0001) == 0) { $crc >>= 1; } else { $crc >>= 1; $crc ^= 0xa001; }
重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理
实现代码:
for($j=0;$j<8;++$j){ if(($crc & 0x0001) == 0){ $crc >>= 1; }else{ $crc >>= 1; $crc ^= 0xa001; } }
重复步骤2到步骤5,进行通讯信息帧下一个字节的处理
实现代码:
for($i=0;$i<strlen($str);$i++){ $crc=($crc>>8) ^ ord($str[$i]); for($j=0;$j<8;++$j){ if(($crc & 0x0001) == 0){ $crc >>= 1; }else{ $crc >>= 1; $crc ^= 0xa001; } } }
将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高低字节进行交换
实现代码:
$crc = (($crc & 0xff) << 8) | (($crc >> 8) & 0xff);
最后得到的CRC寄存器内容即为CRC码,将其返回
实现代码:
return $crc;
完整代码
function crc16($str){
$crc = 0xffff;
for($i=0;$i<strlen($str);$i++){
$crc=($crc>>8) ^ ord($str[$i]);
for($j=0;$j<8;++$j){
if(($crc & 0x0001) == 0){
$crc >>= 1;
}else{
$crc >>= 1;
$crc ^= 0xa001;
}
}
}
$crc = (($crc & 0xff) << 8) | (($crc >> 8) & 0xff);
return $crc;
}
功能调用
$content = "Hello World!";
$result = crc16($content);
echo $result;
完成后,运行输出结果为481
参考文章
总结
这篇教程到这里就结束了,感谢耐心阅读,如果有问题欢迎在评论区留言。
评论区