--- guess-crc.pl 2008/09/29 16:28:49 12 +++ guess-crc.pl 2008/10/01 18:45:35 13 @@ -4,10 +4,29 @@ # # 09/28/08 21:54:24 CEST Dobrica Pavlinusic +# CRC info from: http://stackoverflow.com/questions/149617/how-could-i-guess-a-checksum-algorithm +# and from: http://www.geocities.com/SiliconValley/Pines/8659/crc.htm + +# LRC: Polynomial=0x81; 8 bits; Normal; Initial=0; Final=as calculated +# CRC16: Polynomial=0xa001; 16 bits; Normal; Initial=0; Final=as calculated +# CCITT: Polynomial=0x1021; 16 bits; reverse; Initial=0xffff; Final=0x1d0f +# Xmodem: Polynomial=0x1021; 16 bits; reverse; Initial=0; Final=0x1d0f +# CRC32: Polynomial=0xebd88320; 32 bits; Normal; Initial=0xffffffff; Final=inverted value +# ZIP32: Polynomial=0x04c11db7; 32 bits; Normal; Initial=0xffffffff; Final=as calculated + +# IPX: Polynomial=0x8005; 16 bits; Reverse; Initial=0xffff; Final=as calculated +# ISO 18000-6B: Polynomial=0x1021; 16 bits; Reverse; Initial=0xffff; Final=as calculated +# ISO 18000-6C: Polynomial=0x1021; 16 bits; Reverse; Initial=0xffff; Final=as calculated +# Data must be padded with zeroes to make a multiple of 8 bits +# ISO CRC5: Polynomial=custom; 5 bits; Reverse; Initial=0x9; Final=shifted left by 3 bits +# Data must be padded with zeroes to make a multiple of 8 bits +# EPC class 1: Polynomial=custom 0x1021; 16 bits; Reverse; Initial=0xffff; Final=post processing of 16 zero bits + use strict; use Digest::CRC qw(crc32 crc16 crcccitt crc crc8); use Data::Dump qw/dump/; +use File::Slurp; my $debug = 1 if @ARGV; @@ -17,11 +36,25 @@ } my @check_polys = ( 0x0000 .. 0xffff ); -@check_polys = ( 32833, 43271, 32833, 43271, 19299, 35925, 47123, 49319, 56971 ); +#@check_polys = ( 32833, 43271, 32833, 43271, 19299, 35925, 47123, 49319, 56971 ); # crc16 +@check_polys = ( 31125, 53345, 11642, 24337, 51699, 55122, 15257 ); # ccitt my @check_offset = ( 0,1,2,3 ); @check_offset = ( 1 ); # skip first, second always zero +my @try_polys = ( +{ name => "CRC-16/CITT", width => 16, poly => 0x1021, init => 0xFFFF, refin => 0, refout => 0, xorout => 0x0000 }, +{ name => "XMODEM", width => 16, poly => 0x8408, init => 0x0000, refin => 1, refout => 1, xorout => 0x0000 }, +{ name => "ARC", width => 16, poly => 0x8005, init => 0x0000, refin => 1, refout => 1, xorout => 0x0000 }, +{ name => "CRC-16", width => 16, poly => 0xA001, init => 0x0000, refin => 0, refout => 0, xorout => 0x0000 }, +); + +my @data = ( +'D5 00 05 04 00 11 8C 66', +'D6 00 05 FE 00 05 FA 40', +); +#@data = read_file('all.out') if -e 'all.out'; + my $found_polys; sub check_crc { @@ -31,29 +64,28 @@ #width=>16, init=>0, xorout=>0, refout=>1, poly=>0x8005, refin=>1 # crc16 #0x8408, #0xa001, - width=>16, init=>0, xorout=>0, refout=>1, poly=>$poly,refin=>1 - #width=>16, init=>0xffff, xorout=>0, refout=>1, poly=>$poly, refin=>0 # ccitt + #width=>16, init=>0, xorout=>0, refout=>1, poly=>$poly,refin=>1 # crc16 + width=>16, init=>0xffff, xorout=>0, refout=>1, poly=>$poly, refin=>0 # ccitt ); $ctx->add( $bytes ); my $try = $ctx->digest; - my $str = pack('n*', $try); - warn "## check_crc( $poly, ",dump($bytes)," ) = ",dump( $str, $wanted ) if $debug; - return $str eq $wanted; + my $n = pack('n*', $try); + my $v = pack('n*', $try); + warn "## check_crc( $poly, ",dump($bytes)," ) = ",dump( $n, $v, $wanted ) if $debug; + return $n eq $wanted || $v eq $wanted; } -foreach ( -'D5 00 05 04 00 11 8C 66', -'D6 00 05 FE 00 05 FA 40', -) { +foreach ( @data ) { + my $hex = $_; $hex =~ s/\s+//g; my $bytes = pack('H*', substr($hex, 0, -4)); - warn "?? guess crc ",substr($hex,-4); + print "?? guess crc ",substr($hex,-4),"\n"; my $crc = pack('H4', substr($hex,-4)); - warn "input $_ => ",dump( $bytes, $crc ); + warn "input $_ => ",dump( $bytes, $crc ) if $debug; foreach my $o ( @check_offset ) { my $b = substr( $bytes, $o );