将用 C 编写的 8 位 CRC 函数转换为 PHP
Converting 8 bit CRC function written in C to PHP
我正在尝试将 C 函数转换为进行 8 位 CRC 计算的 PHP。
原C代码:
uint8_t CRCCalc (uint8_t* pointer, uint16_t len) {
uint8_t CRC = 0x00;
uint16_t tmp;
while(len > 0) {
tmp = CRC << 1;
tmp += *pointer;
CRC = (tmp & 0xFF) + (tmp >> 8);
pointer++;
--len;
}
return CRC;
}
我想出的PHP代码是:
function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);
$CRC = 0x00;
$pos = 0;
while($bin_length>0)
{
//$pos = $CRC << 1;
$CRC = ($bin_data[$pos] & 0xFF) + ($bin_data[$pos] >> 8);
$bin_length --;
$pos++ ;
}
return $CRC;
}
由于 PHP 函数的结果不正确,因此缺少某些内容。我对 C 不是很熟悉,所以不确定我的转换是否正确。 C函数给出正确的CRC
例如,如果字符串的十六进制表示为:
280500000805151001240000000010017475260004041001372068828503000000000000
CRC 校验码应该是 D4.
我已经看到了以下关于CRC8计算的链接,但是我好像漏掉了什么
how to generate 8bit crc in php
CRC8-Check in PHP
我也从这个答案中提取了一些转换代码
Convert C to PHP for CRC16 Function
很明显,这两个代码片段没有做同样的事情。在 C 函数中,首先发生的事情是将 CRC(到目前为止计算的)左移 1 位(与将其乘以 2 相同),然后添加数组中的下一个字节,然后重新计算通过将 tmp 的两个字节加在一起得到 CRC。
您的 PHP 示例不进行初始移位,或将先前版本的 CRC 混合到下一个字节的计算中..
($tmp & 0xFF)
只是低字节
($tmp >> 8)
右移8
我还没有测试过,但这是一个快速的尝试。
function CRCCalc ($value, $len) {
$CRC = 0;
while($len > 0) {
$tmp = $CRC << 1; // shift left 1
$tmp += $value;
$CRC = ($tmp & 0xFF) + ($tmp >> 8); // ($tmp & 0xFF) just lower byte ($tmp >> 8: shift right 8
$value++;
$len--;
}
return $CRC;
}
这样试试:
function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);
$CRC = 0;
$tmp = 0;
$pos = 0;
while($bin_length>0)
{
$tmp = $CRC << 1;
$tmp = $tmp + ord($bin_data[$pos]); //Added ord
$CRC = ($tmp + ($tmp >> 8)) & 0xFF;
$bin_length --;
$pos++ ;
}
return $CRC;
}
我正在尝试将 C 函数转换为进行 8 位 CRC 计算的 PHP。
原C代码:
uint8_t CRCCalc (uint8_t* pointer, uint16_t len) {
uint8_t CRC = 0x00;
uint16_t tmp;
while(len > 0) {
tmp = CRC << 1;
tmp += *pointer;
CRC = (tmp & 0xFF) + (tmp >> 8);
pointer++;
--len;
}
return CRC;
}
我想出的PHP代码是:
function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);
$CRC = 0x00;
$pos = 0;
while($bin_length>0)
{
//$pos = $CRC << 1;
$CRC = ($bin_data[$pos] & 0xFF) + ($bin_data[$pos] >> 8);
$bin_length --;
$pos++ ;
}
return $CRC;
}
由于 PHP 函数的结果不正确,因此缺少某些内容。我对 C 不是很熟悉,所以不确定我的转换是否正确。 C函数给出正确的CRC
例如,如果字符串的十六进制表示为: 280500000805151001240000000010017475260004041001372068828503000000000000
CRC 校验码应该是 D4.
我已经看到了以下关于CRC8计算的链接,但是我好像漏掉了什么
how to generate 8bit crc in php CRC8-Check in PHP
我也从这个答案中提取了一些转换代码 Convert C to PHP for CRC16 Function
很明显,这两个代码片段没有做同样的事情。在 C 函数中,首先发生的事情是将 CRC(到目前为止计算的)左移 1 位(与将其乘以 2 相同),然后添加数组中的下一个字节,然后重新计算通过将 tmp 的两个字节加在一起得到 CRC。
您的 PHP 示例不进行初始移位,或将先前版本的 CRC 混合到下一个字节的计算中..
($tmp & 0xFF)
只是低字节
($tmp >> 8)
右移8
我还没有测试过,但这是一个快速的尝试。
function CRCCalc ($value, $len) {
$CRC = 0;
while($len > 0) {
$tmp = $CRC << 1; // shift left 1
$tmp += $value;
$CRC = ($tmp & 0xFF) + ($tmp >> 8); // ($tmp & 0xFF) just lower byte ($tmp >> 8: shift right 8
$value++;
$len--;
}
return $CRC;
}
这样试试:
function crc8_calc($hex_string)
{
$bin_data = pack('H*',$hex_string);
$bin_length = strlen($bin_data);
$CRC = 0;
$tmp = 0;
$pos = 0;
while($bin_length>0)
{
$tmp = $CRC << 1;
$tmp = $tmp + ord($bin_data[$pos]); //Added ord
$CRC = ($tmp + ($tmp >> 8)) & 0xFF;
$bin_length --;
$pos++ ;
}
return $CRC;
}