/[RFID]/guess-crc.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /guess-crc.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (hide annotations)
Wed Oct 1 18:45:35 2008 UTC (15 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 3692 byte(s)
added more info
1 dpavlin 7 #!/usr/bin/perl -w
2    
3     # guess-crc.pl
4     #
5     # 09/28/08 21:54:24 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
6    
7 dpavlin 13 # CRC info from: http://stackoverflow.com/questions/149617/how-could-i-guess-a-checksum-algorithm
8     # and from: http://www.geocities.com/SiliconValley/Pines/8659/crc.htm
9    
10     # LRC: Polynomial=0x81; 8 bits; Normal; Initial=0; Final=as calculated
11     # CRC16: Polynomial=0xa001; 16 bits; Normal; Initial=0; Final=as calculated
12     # CCITT: Polynomial=0x1021; 16 bits; reverse; Initial=0xffff; Final=0x1d0f
13     # Xmodem: Polynomial=0x1021; 16 bits; reverse; Initial=0; Final=0x1d0f
14     # CRC32: Polynomial=0xebd88320; 32 bits; Normal; Initial=0xffffffff; Final=inverted value
15     # ZIP32: Polynomial=0x04c11db7; 32 bits; Normal; Initial=0xffffffff; Final=as calculated
16    
17     # IPX: Polynomial=0x8005; 16 bits; Reverse; Initial=0xffff; Final=as calculated
18     # ISO 18000-6B: Polynomial=0x1021; 16 bits; Reverse; Initial=0xffff; Final=as calculated
19     # ISO 18000-6C: Polynomial=0x1021; 16 bits; Reverse; Initial=0xffff; Final=as calculated
20     # Data must be padded with zeroes to make a multiple of 8 bits
21     # ISO CRC5: Polynomial=custom; 5 bits; Reverse; Initial=0x9; Final=shifted left by 3 bits
22     # Data must be padded with zeroes to make a multiple of 8 bits
23     # EPC class 1: Polynomial=custom 0x1021; 16 bits; Reverse; Initial=0xffff; Final=post processing of 16 zero bits
24    
25 dpavlin 7 use strict;
26    
27     use Digest::CRC qw(crc32 crc16 crcccitt crc crc8);
28     use Data::Dump qw/dump/;
29 dpavlin 13 use File::Slurp;
30 dpavlin 7
31 dpavlin 12 my $debug = 1 if @ARGV;
32    
33 dpavlin 7 sub hex2b {
34     my $hex = shift;
35     return map { hex($_) } split(/\s+/, $hex);
36     }
37    
38 dpavlin 12 my @check_polys = ( 0x0000 .. 0xffff );
39 dpavlin 13 #@check_polys = ( 32833, 43271, 32833, 43271, 19299, 35925, 47123, 49319, 56971 ); # crc16
40     @check_polys = ( 31125, 53345, 11642, 24337, 51699, 55122, 15257 ); # ccitt
41 dpavlin 7
42 dpavlin 12 my @check_offset = ( 0,1,2,3 );
43     @check_offset = ( 1 ); # skip first, second always zero
44    
45 dpavlin 13 my @try_polys = (
46     { name => "CRC-16/CITT", width => 16, poly => 0x1021, init => 0xFFFF, refin => 0, refout => 0, xorout => 0x0000 },
47     { name => "XMODEM", width => 16, poly => 0x8408, init => 0x0000, refin => 1, refout => 1, xorout => 0x0000 },
48     { name => "ARC", width => 16, poly => 0x8005, init => 0x0000, refin => 1, refout => 1, xorout => 0x0000 },
49     { name => "CRC-16", width => 16, poly => 0xA001, init => 0x0000, refin => 0, refout => 0, xorout => 0x0000 },
50     );
51    
52     my @data = (
53     'D5 00 05 04 00 11 8C 66',
54     'D6 00 05 FE 00 05 FA 40',
55     );
56     #@data = read_file('all.out') if -e 'all.out';
57    
58 dpavlin 12 my $found_polys;
59    
60     sub check_crc {
61     my ( $poly, $bytes, $wanted ) = @_;
62     my $ctx = Digest::CRC->new(
63     #width=>16, init=>0xffff, xorout=>0, refout=>1, poly=>0x1021, refin=>0 # ccitt
64     #width=>16, init=>0, xorout=>0, refout=>1, poly=>0x8005, refin=>1 # crc16
65     #0x8408,
66     #0xa001,
67 dpavlin 13 #width=>16, init=>0, xorout=>0, refout=>1, poly=>$poly,refin=>1 # crc16
68     width=>16, init=>0xffff, xorout=>0, refout=>1, poly=>$poly, refin=>0 # ccitt
69 dpavlin 12 );
70     $ctx->add( $bytes );
71     my $try = $ctx->digest;
72 dpavlin 13 my $n = pack('n*', $try);
73     my $v = pack('n*', $try);
74     warn "## check_crc( $poly, ",dump($bytes)," ) = ",dump( $n, $v, $wanted ) if $debug;
75     return $n eq $wanted || $v eq $wanted;
76 dpavlin 12 }
77    
78 dpavlin 13 foreach ( @data ) {
79    
80 dpavlin 7 my $hex = $_;
81     $hex =~ s/\s+//g;
82    
83     my $bytes = pack('H*', substr($hex, 0, -4));
84    
85 dpavlin 13 print "?? guess crc ",substr($hex,-4),"\n";
86 dpavlin 7 my $crc = pack('H4', substr($hex,-4));
87    
88 dpavlin 13 warn "input $_ => ",dump( $bytes, $crc ) if $debug;
89 dpavlin 7
90 dpavlin 12 foreach my $o ( @check_offset ) {
91 dpavlin 7 my $b = substr( $bytes, $o );
92    
93 dpavlin 12 foreach my $poly ( @check_polys ) {
94 dpavlin 7
95     print "## poly $poly\n" if $poly % 1000 == 0;
96    
97 dpavlin 12 if ( check_crc( $poly, $b, $crc ) ) {
98     warn "HIT: $o poly: $poly\n";
99     $found_polys->{$poly}->{$o}++;
100 dpavlin 7 }
101     }
102     }
103     }
104    
105 dpavlin 12 print "FOUND polys = ", dump( $found_polys );

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26