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 Gave you both methods of reaching the same number -- just to show how it's done.
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):
Polynomial's hard coded though --- though it's a good trade when you only need CCITT and speed is more important than versatility.
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