netbookpros Posted May 27, 2011 Share Posted May 27, 2011 I need to produce 4 byte CRC32 checksums for UDP packets sent to an rcon tool for an online game. The (brief) specification for formatting these UDP packets is here: http://www.battleye.com/downloads/BERConProtocol.txt I have been converting the results of the CRC32() to hex and inserting it successfully in the correct part of the packet. The checksum result however is different from one that I packet captured from a working rcon tool. I have tried various methods of converting the int that CRC32 produces but have been unsuccessful in producing the correct checksum. For reference below is the captured correct packet from the working tool. All data is the same as the packets my tool produces except for the checksum. The checksum is bytes 3,4,5 & 6. and is formed (to my understanding) by performing a CRC32 check on the subsequent bytes. (From Smartsniff) 00000000 42 45 D5 C3 FB ED FF 00 61 62 63 64 65 31 32 BE...... abcde12 If anyone has a working CRC32 class that could reproduce the successful hash above or has any pointers in the correct direction I would be very thankful. Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/ Share on other sites More sharing options...
PFMaBiSmAd Posted May 27, 2011 Share Posted May 27, 2011 Did you read this note in the crc32 documentation - Because PHP's integer type is signed, and many crc32 checksums will result in negative integers, you need to use the "%u" formatter of sprintf() or printf() to get the string representation of the unsigned crc32 checksum. Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/#findComment-1220949 Share on other sites More sharing options...
netbookpros Posted May 27, 2011 Author Share Posted May 27, 2011 I have been using sprintf() but it is still producing incorrect checksums. Could this be because I am running x64 win7? EDIT: I'm fairly inexperienced so this could be down to a really silly mistake or misunderstanding. I won't take it to heart if you tell me I've done something stupid! $str = (chr(0xFF).chr(0x00).chr(0x61).chr(0x62).chr(0x63).chr(0x64).chr(0x65).chr(0x31).chr(0x32)); // String Including the LEAD two chars (FF 00) [i have tried it without these.] $crcint = crc32($str); $crc2 = sprintf("%u", $crcint);; $crcstr = dechex($crcint); //Below code is an inefficient way of turning the result of dechex into formatted hex e.g 0xFF $x = ('0x'); $a = substr($crcstr, 0, 2); $a = $x.$a; $b = substr($crcstr, 2, 4); $b = $x.$b; $c = substr($crcstr, 4, 6); $c = $x.$c; $d = substr($crcstr, 6, ; $d = $x.$d; //Then each character is inserted into the final message $msg = chr(0x42).chr(0x45).chr($a).chr($b).chr($c).chr($d).chr(0xFF).chr(0x00).chr(0x61).chr(0x62).chr(0x63).chr(0x64).chr(0x65).chr(0x31).chr(0x32); Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/#findComment-1221143 Share on other sites More sharing options...
netbookpros Posted May 27, 2011 Author Share Posted May 27, 2011 Ok I've now revised my code and used some other peoples functions to fix a few things. It now produces the hex checksum: DF C3 FB ED The target checksum is: D5 C3 FB ED So close! Anyone any ideas why it would be getting this only slightly wrong? A larger sample of the revised code below: <?php function connect (){ $this->security = new security(); $this->connection = fsockopen("udp://$this->server_ip", $this->server_port, &$errno, &$errstr, 5); stream_set_timeout($this->connection, 5); if (!$this->connection){ echo ("Connection Failed: $errno, $errstr"); } else{ $str = (chr(0xFF).chr(0x00).chr(0x61).chr(0x62).chr(0x63).chr(0x64).chr(0x65).chr(0x31).chr(0x32)); $crcunsign = $this->computeUnsignedCRC32($str); $crcstr = $this->dec_to_hex($crcunsign); $x = ('0x'); $a = substr($crcstr, 0, 2); $a = $x.$a; $b = substr($crcstr, 2, 2); $b = $x.$b; $c = substr($crcstr, 4, 2); $c = $x.$c; $d = substr($crcstr, 6, 2); $d = $x.$d; echo ($d.$c.$b.$a); $msg = chr(0x42).chr(0x45).chr($d).chr($c).chr($b).chr($a).chr(0xFF).chr(0x00).chr(0x61).chr(0x62).chr(0x63).chr(0x64).chr(0x65).chr(0x31).chr(0x32); fwrite($this->connection,$msg); $this->listen(); } } function listen(){ $last_message = fread($this->connection,16); } function send($data){ } function computeUnsignedCRC32($str){ sscanf(crc32($str), "%u", $var); return $var; } function dec_to_hex($dec) { $sign = ""; // suppress errors if( $dec < 0){ $sign = "-"; $dec = abs($dec); } $hex = Array( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f' ); do { $h = $hex[($dec%16)] . $h; $dec /= 16; } while( $dec >= 1 ); return $sign . $h; } } ?> Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/#findComment-1221257 Share on other sites More sharing options...
netbookpros Posted May 27, 2011 Author Share Posted May 27, 2011 Ok further update. Tested on a 32bit server and managed to produce the correct checksum, confirming that it is due to my OS being 64bit. Any ideas on a fix for this problem? Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/#findComment-1221329 Share on other sites More sharing options...
netbookpros Posted June 5, 2011 Author Share Posted June 5, 2011 OK problem Solved: For the reference of anyone who stumbles across this. The correct way to do it is as follows. Should work on both 32 and 64 bit. Adding zero to the result of the checksum fixed it for me. <?php sscanf(crc32($str), "%u", $crc); $crchex = dechex($crc + 0); ?> Link to comment https://forums.phpfreaks.com/topic/237598-php5-crc32/#findComment-1225550 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.