2

为了扩展和解释上面发布的链接,这里是 PHP 中的一个函数,用于获取字符串数据的 CRC16 校验和:

    function crc16($data) {
        $crc = 0xAC6F;
        $len = strlen($data);
        $i = 0;
        while ($len--) {
            $crc ^= reversebyte(ord($data[$i++])) << 8;
            $crc &= 0xffff;
            for ($j = 0; $j < 8; $j++){
                $crc = ($crc & 0x8000) ? ($crc << 1) ^ 0x8005 : $crc << 1;
                $crc &= 0xffff;
            }
        }
        $crc ^= 0x0000;
        $crc = reversebits($crc);
        return $crc;
    }

    function reversebyte($byte) {
        $ob = 0;
        $b = (1 << 7);
        for ($i = 0; $i <= 7; $i++) {
            if (($byte & $b) !== 0) {
                $ob |= (1 << $i);
            }
            $b >>= 1;
        }
        return $ob;
    }

    function reversebits($cc) {
        $ob = 0;
        $b = (1 << 15);
        for ($i = 0; $i <= 15; $i++) {
            if (($cc & $b) !== 0) {
                $ob |= (1 << $i);
            }
            $b >>= 1;
        }
        return $ob;
    }

    Poly = 0x8005
    Init = 0xAC6F
    Xor = 0x0000
    Refin = True
    Refout = True

如果您不想添加反射,请在函数 crc16() 中替换这些行:

替换Refin = True:

    $crc ^= reversebyte(ord($data[$i++])) << 8;

使用 Refin = False:

    $crc ^= ord($data[$i++]) << 8;

替换 Refout = True:

    $crc = reversebits($crc);

使用 Refout = False (删除这一整行):

    $crc = reversebits($crc); //remove me
4

1 回答 1

0

要编写自己的 CRC 函数,我建议您阅读The Painless Guide to CRC Error Detection Algorithms。它为不同类型的实现提供伪代码,包括简单、朴素的一种和改进的表驱动实现。该指南还涵盖了您的要求,例如 refin、refout 等。

剩下的唯一真正困难是将伪代码或 C 代码转换为 php,但由于 php具有与 C 相同的位运算符,这应该不是一个挑战。

于 2014-04-14T11:20:36.447 回答