将用C编写的8位CRC函数转换为PHP

时间:2015-05-11 11:53:16

标签: php c crc code-conversion

我正在尝试将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

3 个答案:

答案 0 :(得分:3)

很明显,这两个代码片段不会做同样的事情。在C函数中,首先发生的事情是将CRC(你到目前为止计算得到的)移位1位(与乘以2相同),然后从数组中添加下一个字节,然后通过将tmp的两个字节加在一起来重新计算CRC。

你的PHP示例没有进行初始移位,或者将先前版本的CRC混合到下一个字节的计算中。

答案 1 :(得分:2)

试试这样:

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 :(得分:0)

($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;
}