【问题标题】:Converting 8 bit CRC function written in C to PHP将用 C 编写的 8 位 CRC 函数转换为 PHP
【发布时间】:2015-05-11 11:53:16
【问题描述】:

我正在尝试将 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 代码?请注意,C 代码正在处理 16 位 变量 tmp。为什么你省略了&lt;&lt; shift 操作?另请注意,tmp += *pointer; 表示 tmp = tmp + *pointernot tmp = *pointer
  • 示例中的 C 代码无法编译。
  • @specializt 因为Pointer++中的拼写错误?
  • 移位运算符被错误地注释掉了。 JeremyP 已经更正了 C 代码中的错字。谢谢

标签: php c crc code-conversion


【解决方案1】:

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

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

【讨论】:

    【解决方案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;
    }
    

    【讨论】:

    • 不,我比快13秒! :o)
    • 我击败了你们两个 :-) 。 @Misunderstood 在他/她的代码中有错误。
    • @JeremyP 他,还没睡,一夜没睡。我不知道通过引用传递了什么。所以我称之为价值。
    • 这个答案也有一个错误。你需要这个$CRC = (($tmp &amp; 0xFF) + ($tmp &gt;&gt; 8)) &amp; 0xFF;
    • 不确定它是否真的有影响(除非$CRC 会在某个时候溢出),但我会编辑它。
    【解决方案3】:

    ($tmp &amp; 0xFF) 只是低字节

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

    【讨论】:

    • 什么是$value?为什么要直接将其添加到 CRC 中,然后将其递增?它应该是一个数组或一个指针,然后将它指向的内容添加到 CRC
    猜你喜欢
    • 1970-01-01
    • 2012-08-04
    • 2015-01-17
    • 2011-11-01
    • 1970-01-01
    • 2017-12-13
    • 2016-01-03
    • 1970-01-01
    • 2020-10-30
    相关资源
    最近更新 更多