How to calculate CRC16 CCITT in PHP HEX?

2019-02-18 12:28发布

问题:

I'm trying to use a PHP CRC16 CCITT function to calculate the checksum.

A device sends me a PACKET with Checksum included:

10 00 00 00 00 00 00 00 12 51 09 08 00 18 00 04 02 14 00 0c 00 0c 02 1c 00 02 00 00 00 00 00 00 a0 77

The checksum is at the end: a0 77

I've tried using

How to calculate crc16 in php

Convert C to PHP for CRC16 Function

With no success, the CRC 16 Calculations return: E6 F4 instead of a0 77

I get the correct Hex information returned, when I lookup:

100000000000000012510908001800040214000c000c021c0002000000000000

on the website http://www.lammertbies.nl/comm/info/crc-calculation.html but I cannot reproduce it. (make sure to select the input type to HEX)

Can you please help me figure out how to get the crc16 CCITT of the string of hex values

100000000000000012510908001800040214000c000c021c0002000000000000

I'm looking for the checksum a0 77

回答1:

I was able to produce the same checksum with implementation like below:

define('CRC16POLYN', 0x1021);

function CRC16Normal($buffer) {
    $result = 0xFFFF;
    if (($length = strlen($buffer)) > 0) {
        for ($offset = 0; $offset < $length; $offset++) {
            $result ^= (ord($buffer[$offset]) << 8);
            for ($bitwise = 0; $bitwise < 8; $bitwise++) {
                if (($result <<= 1) & 0x10000) $result ^= CRC16POLYN;
                $result &= 0xFFFF;
            }
        }
    }
    return $result;
}

echo dechex(CRC16Normal(hex2bin('100000000000000012510908001800040214000c000c021c0002000000000000')));

Above gives a077 on output.

Code snippet found on https://forums.digitalpoint.com/threads/php-define-function-calculate-crc-16-ccitt.2584389/



回答2:

I found out from the Deplhi function how it works. It gets an byte Array, instead of Hex string for doing the job. Here is the code:

// $commands = [0x35, 0x02, 0x02, 0x00, 0x10, 0x03];       // => 0x5ba3
$commands = [0x44, 0x02, 0x02, 0x01, 0x10, 0x03];       // => 0x55c0
var_dump(dechex(getChecksum($commands)));

function getChecksum($byteArray) {
    $polynom = 0x8408;
    $in_crc = 0x0000;
    for ($i = 0; $i < sizeof($byteArray); $i++) {
        for ($n = 0; $n < 8; $n++) {
            if((($byteArray[$i] & 0x0001) ^ $in_crc) & 0x0001) 
                $in_crc = ($in_crc >> 1) ^ $polynom;
            else 
                $in_crc = $in_crc >> 1;
            $byteArray[$i] = $byteArray[$i] >> 1;
        }
        $result = $in_crc;
    }
    return $result;
}

The solution can be proved on this Online CRC Calculator. The Algorithm used is CRC-16/KERMIT.



标签: php hex crc crc16