How to calculate CRC16 CCITT in PHP HEX?

后端 未结 3 1641
深忆病人
深忆病人 2021-01-13 03:30

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

相关标签:
3条回答
  • 2021-01-13 04:04

    So I was looking for how to calculate checksum according to [ISO/IEC 13239] using the polynomial '1021' (hex) and initial value 'FFFF' (hex). I found this link which can calculate many types of CRC. After submitting my input, I wanted the value of the field CRC-CCITT (0xFFFF), which is something like this:

    So I took the JS function (in the .js file, the function name is CRCFFFF ) that calculated the CCITT, and created the PHP version of it.

    function crcChecksum($str) {
        // The PHP version of the JS str.charCodeAt(i)
        function charCodeAt($str, $i) {
            return ord(substr($str, $i, 1));
        }
    
        $crc = 0xFFFF;
        $strlen = strlen($str);
        for($c = 0; $c < $strlen; $c++) {
            $crc ^= charCodeAt($str, $c) << 8;
            for($i = 0; $i < 8; $i++) {
                if($crc & 0x8000) {
                    $crc = ($crc << 1) ^ 0x1021;
                } else {
                    $crc = $crc << 1;
                }
            }
        }
        $hex = $crc & 0xFFFF;
        $hex = dechex($hex);
        $hex = strtoupper($hex);
    
        return $hex;
    }
    
    $result = crcChecksum('replace with your string here');// In my case, this gave me the desired output, which is '627B' (without '0x')
    

    In case you need the '0x', just add it:

    $result = '0x' . crcChecksum('replace with your string here');// result = '0x627B'
    
    0 讨论(0)
  • 2021-01-13 04:29

    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/

    0 讨论(0)
  • 2021-01-13 04:29

    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.

    0 讨论(0)
提交回复
热议问题