I'm trying to write a program to calculate a 32-bit CRC from an imput file by emulating the hardware representation on pg. 195 of Data & Computer Communications (8th ed. Stallings). There's a problem in my program's logic in at least one spot. Am I iterating an array in the wrong direction or popping when I should unshift?
Here's my code thus far:
#!/usr/bin/perl -w use strict; use warnings; use String::CRC32; # Poly: X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^ +1+1 # Gen: 100000100110000010001110110110111 my @msg; my @bin_msg; my @gen = qw(0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 + 1 1 1); my @crc = qw(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0); my $crc = 0; my $old_crc = 0; my $built_in_crc = 0; get_input(); my_crc(); built_in_crc(); display(); sub get_input { local $/ = undef; my $file = <>; my @file = split(/0x/, $file); @msg = split(//, $file[0]); if ($file[1]) { $old_crc = sprintf('0x%s', $file[1]); } else { $old_crc = 0; } $built_in_crc = built_in_crc($file[0]); } sub my_crc { foreach (@msg) { push(@bin_msg, split(//, sprintf('%08b', ord($_)))); } print "\n"; while (@bin_msg) { my $bit = shift(@bin_msg); print "bit: $bit\t\t"; push(@crc, $bit); shift(@crc); if ($bit == 1) { for (my $i = 0; $i < 32; $i++) { if ($gen[$i] == 1) { $crc[$i] ^= 1; } } } print @crc, "\n"; } } sub built_in_crc { my $tmp = $_[0] || warn "$!\n"; return crc32($tmp); + } sub display { my $x = ''; foreach (@crc) { $x .= $_; } print "Msg:\t\t\'", @msg, "\'\n"; print "Gen:\t\t", @gen, "\n"; printf "Old CRC:\t%s\n", $old_crc; printf "New CRC:\t%s", `python -c "print hex(0b$x)"`; printf "Lib CRC:\t%#x\t(String::CRC32)\n\n", $built_in_crc; }
And the output:
bit: 0 00000000000000000000000000000000 bit: 1 00000100110000010001110110110110 bit: 0 00001001100000100011101101101100 bit: 1 00010111110001010110101101101110 bit: 0 00101111100010101101011011011100 bit: 1 01011011110101001011000000001110 bit: 1 10110011011010000111110110101010 bit: 0 01100110110100001111101101010100 Msg: 'V' Gen: 00000100110000010001110110110111 Old CRC: 0x500a1b4c New CRC: 0x66d0fb54 Lib CRC: 0x500a1b4c (String::CRC32)
Old, New and Lib CRC should match...but my result (New CRC) doesn't.
Update: I worked out the same message 'V' by hand and got the same result as my program '0x66d0fb54'. This means that the program is doing exactly what I expected it to do. So my problem must be in my interpretation of the hardware's logic.
I think I should be feeding the bit-string representation of the message, MSB first into the crc array, if the current bit is a 1, then I iterate through the crc and gen arrays, xoring the the corresponding index in crc whenever I encounter a 1 in the gen array.
Any insights?

In reply to CRC32 program logic problem by zhespelt

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.