1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

PHP define function CALCULATE CRC-16 CCITT

Discussion in 'PHP' started by esgllcinc, Oct 31, 2012.

  1. #1
    DO anyone have a php function that will calculate CRC-16 CCITT checksum using the selected region.
     
    Solved! View solution.
    esgllcinc, Oct 31, 2012 IP
  2. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #2
    ThePHPMaster, Oct 31, 2012 IP
  3. #3
    Try these:

    
    <?php
    // CCITT, X24
    define(CRC16POLYN,0x1021);
    define(CRC16POLYI,0x8408);
    
    // for "STANDARD" use 0x8005 and 0xA001
    
    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; /* gut the overflow as php has no 16 bit types */
    			}
    		}
    	}
    	return $result;
    }
    
    function CRC16Inverse($buffer) {
    	$result = 0xFFFF;
    	if ( ($length = strlen($buffer)) > 0) {
    		for ($offset = 0; $offset < $length; $offset++) {
    			$result ^= ord($buffer[$offset]);
    			for ($bitwise = 0; $bitwise < 8; $bitwise++) {
    				$lowBit = $result & 0x0001;
    				$result >>= 1;
    				if ($lowBit) $result ^= CRC16POLYI;
    			}
    		}
    	}
    	return $result;
    }
    
    
    echo '
    	0x',dechex(CRC16Normal('123456789')),' == 0x29B1<br />
    	0x',dechex(CRC16Normal('abc')),' == 0x514A<br />
    	0x',dechex(CRC16Normal('ABC')),' == 0xF508<br />
    	0x',dechex(CRC16Normal('This is a string')),' == 0x4BE9<br />
    	<br />
    	0x',dechex(CRC16Inverse('123456789')),' == 0x29B1<br />
    	0x',dechex(CRC16Inverse('abc')),' == 0x514A<br />
    	0x',dechex(CRC16Inverse('ABC')),' == 0xF508<br />
    	0x',dechex(CRC16Inverse('This is a string')),' == 0x4BE9<br />';
    ?>
    
    Code (markup):
    Should work good for you... and another of those routines that I really wish higher level languages gave you access to the carry flag on the processor :D

    Gave you both methods of reaching the same number -- just to show how it's done.
     
    deathshadow, Nov 1, 2012 IP
  4. esgllcinc

    esgllcinc Peon

    Messages:
    14
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    This works as well and its shorter

    <?php
    function crc16($data)
     {
       $crc = 0xFFFF;
       for ($i = 0; $i < strlen($data); $i++)
       {
         $x = (($crc >> 8) ^ ord($data[$i])) & 0xFF;
         $x ^= $x >> 4;
         $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
       }
       return $crc;
     }
    ?>
    Code (markup):
     
    esgllcinc, Nov 9, 2012 IP
  5. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #5
    Polynomial's hard coded though --- though it's a good trade when you only need CCITT and speed is more important than versatility.
     
    deathshadow, Nov 10, 2012 IP
  6. noobee80

    noobee80 Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    1
    #6
    hello@community,

    I have a question to this old post. :( First, THANKS for the code :):)
    I have a message in hex "80 00 00 03" crc-ccitt kermit. The checksum (checked with lammertbies.nl) is "f5 1f". When I use the the php-code above, I did not get that checksum. I know, that I do not have to use the polynom 0x1021. The right polynom is the revers one 0x8408. Also the result is not the right one for me. The correct result is "$result = 0x0000" instead of "$result = 0xFFFF". But that does not solve the problem. I did not get the right checksum for my message "80 00 00 03".
    Do I have to change the php-code or what is the error? Please help me
     
    noobee80, Oct 13, 2016 IP