I am trying to convert a C function to PHP that does 8 bit CRC calculation.
我正在尝试将C函数转换为执行8位CRC计算的PHP。
The original C code:
原始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;
}
The PHP code that I have come up with is:
我提出的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;
}
There is something that is missing as the results from the PHP functions are not correct. I am not very familiar with C, so not sure if my conversion is correct. The C function gives out the correct CRC
由于PHP函数的结果不正确,因此缺少某些内容。我对C不太熟悉,所以不确定我的转换是否正确。 C函数给出正确的CRC
For example, if the hex representation of the string is: 280500000805151001240000000010017475260004041001372068828503000000000000
例如,如果字符串的十六进制表示形式为:280500000805151001240000000010017475260004041001372068828503000000000000
The CRC should be D4.
CRC应该是D4。
I have already seen the following links for CRC8 calculation, but I seem to missing something
我已经看到了CRC8计算的以下链接,但我似乎错过了一些东西
how to generate 8bit crc in php CRC8-Check in PHP
如何在PHP中生成8bit crc CRC8-Check in PHP
I have taken some bits of my conversion code from this answer too Convert C to PHP for CRC16 Function
我从这个答案中获取了一些我的转换代码也将C转换为PHP用于CRC16功能
3 个解决方案
#1
Try it like this:
试试这样:
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;
}
#2
It's obvious that the two code fragments don't do the same thing. In the C function, the first thing that happens is you shift the CRC (that you've calculated so far) left by 1 bit (same as multiplying it by 2), then you add the next byte from the array, then you recalculate the CRC by adding the two bytes of tmp together.
很明显,这两个代码片段不会做同样的事情。在C函数中,首先发生的事情是你将CRC(你到目前为止计算的)移位1位(与乘以2相同),然后从数组中添加下一个字节,然后重新计算CRC将两个字节的tmp加在一起。
Your PHP example doesn't do the initial shift, or mix in the previous version of the CRC into the calculation for the next byte..
您的PHP示例不执行初始移位,或者将先前版本的CRC混合到下一个字节的计算中。
#3
($tmp & 0xFF)
just lower byte
($ tmp&0xFF)只是低字节
($tmp >> 8)
shift right 8
($ tmp >> 8)右移8
I have not tested, but this is a quick attempt.
我没有测试过,但这是一个快速的尝试。
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;
}
#1
Try it like this:
试试这样:
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;
}
#2
It's obvious that the two code fragments don't do the same thing. In the C function, the first thing that happens is you shift the CRC (that you've calculated so far) left by 1 bit (same as multiplying it by 2), then you add the next byte from the array, then you recalculate the CRC by adding the two bytes of tmp together.
很明显,这两个代码片段不会做同样的事情。在C函数中,首先发生的事情是你将CRC(你到目前为止计算的)移位1位(与乘以2相同),然后从数组中添加下一个字节,然后重新计算CRC将两个字节的tmp加在一起。
Your PHP example doesn't do the initial shift, or mix in the previous version of the CRC into the calculation for the next byte..
您的PHP示例不执行初始移位,或者将先前版本的CRC混合到下一个字节的计算中。
#3
($tmp & 0xFF)
just lower byte
($ tmp&0xFF)只是低字节
($tmp >> 8)
shift right 8
($ tmp >> 8)右移8
I have not tested, but this is a quick attempt.
我没有测试过,但这是一个快速的尝试。
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;
}