自定义CRC16带位反射

时间:2014-04-14 04:41:17

标签: php checksum crc16

要扩展并给出可能与上面发布的链接一致的解释,这里是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

1 个答案:

答案 0 :(得分:0)

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

剩下的唯一真正的困难是将伪代码或C代码翻译成php,但是因为php has just the same bitwise operators as C,这不应该是一个挑战。