将CRC alrgorythm从C转换为PHP

时间:2016-06-28 19:12:30

标签: php c crc

解决

我在C上有以下代码,我必须在PHP上编写

const U16 crc_table[16] = {
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};

U16 CalculateCrc(char *data, U32 len) {
    U32 i;
    U16 crc = 0;

    while (len--) {
        i = (crc >> 12) ^ (*data >> 4);
        crc = crc_table[i & 0x0F] ^ (crc << 4);
        i = (crc >> 12) ^ (*data >> 0);
        crc = crc_table[i & 0x0F] ^ (crc << 4);
        data++;
    }
    return (crc & 0xFFFF);
}

在基本的逻辑翻译中,我到目前为止做到了这一点:

public function crc($data){

        $i = 0;
        $crc = 0;

        /* @var $crc_table array */
        $crc_table = array
            (
                0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
                0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
            );

        for($a = 0; $a < strlen($data); $a++){
            $i = (($crc >> 12) ^ ($data[$a] >> 4));
            $crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
            $i = (($crc >> 12) ^ $data[$a]);
            $crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
        }



        return ($crc & 0xFFFF);

    }

结果不匹配,我不是这方面的专家。有什么建议吗?

修改

谢谢“squeamish ossifrage”! 根据你的帮助,我现在正在使用这个功能:

private function crc($data){

        $i = 0;
        $crc = 0;

        $crc_table = array
            (
                0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
                0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
            );

        $data = hex2bin($data);
        $l = 0;
        while($l < strlen($data)){

            $byte = $data[$l];
            $i = (($crc >> 12) ^ (ord($byte) >> 4));
            $crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
            $i = (($crc >> 12) ^ (ord($byte) >> 4));
            $crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
            $l++;
        }

        return ($crc & 0xFFFF);

    }

我用“Hello world”测试它为十六进制“48656C6C6F20776F726C64”。 在C上我得到37278并在PHP函数56062以上。

现在有线索吗?

修改

好吧,我的不好......问题已经解决了,但经过这么多测试后我感到很困惑。

这是我的第一个代码版本,建议修正为“squeamish ossifrage”:

$byte = $data[$l];
$i = (($crc >> 12) ^ (ord($byte) >> 4));
$crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
$i = (($crc >> 12) ^ **ord($byte));**
$crc = ($crc_table[$i & 0x0F] ^ ($crc << 4));
$l++;

谢谢!

1 个答案:

答案 0 :(得分:2)

您的代码无效,因为您正在计算整数和字符串变量的XOR产品:

$i = (($crc >> 12) ^ ($data[$a] >> 4));

此处$data[$a]是输入数据的子字符串。您应该使用ord()将其转换为整数:

$i = (($crc >> 12) ^ (ord($data[$a]) >> 4));

编辑:对PHP代码进行此更改后,两个函数中的字符串Hello, world!将哈希值为31454.。