侧边栏壁纸
博主头像
小斯小站 博主等级

用心分享技术

  • 累计撰写 37 篇文章
  • 累计创建 75 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

使用PHP实现CRC16算法

SCH小斯
2024-04-25 / 0 评论 / 0 点赞 / 30 阅读 / 4458 字
温馨提示:
本文最后更新于 2024-04-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

简介

Cyclic Redundancy Check循环冗余检验,是基于数据计算一组效验码,用于核对数据传输过程中是否被更改或传输错误。

计算流程

  1. 预置1个16位的寄存器为十六进制0xFFFF;称此寄存器为CRC寄存器

实现代码:

$crc = 0xFFFF;
  1. 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,结果放入CRC寄存器

实现代码:

$crc=($crc>>8) ^ ord($str[$i]);
  1. 把CRC寄存器的内容右移一位(朝低位)用0填补,并检查右移后的移除位

实现代码:

($crc & 0x0001) == 0
  1. 如果移出位为0:重复第3步(再次右移一位);如果移出位为1:CRC寄存器0xA001进行异或

实现代码:

if (($crc & 0x0001) == 0) {
	$crc >>= 1;
} else {
	$crc >>= 1;
	$crc ^= 0xa001;
}
  1. 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理

实现代码:

for($j=0;$j<8;++$j){
	if(($crc & 0x0001) == 0){
		$crc >>= 1;
	}else{
		$crc >>= 1;
		$crc ^= 0xa001;
	}
}
  1. 重复步骤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;
		}
	}
}
  1. 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高低字节进行交换

实现代码:

$crc = (($crc & 0xff) << 8) | (($crc >> 8) & 0xff);
  1. 最后得到的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

参考文章

总结

这篇教程到这里就结束了,感谢耐心阅读,如果有问题欢迎在评论区留言。

0

评论区