Search code examples
perlhashcrc16

Perl - How to calculate CRC16 of N bytes from array M-dimensional (with N<M) using Digest::CRC


I need to calculate a CRC16 of N-bytes (5 in the example, for the sake of simplicity) extracted from a binary file of size M (a pair of Kb, not so relevant for my scopes).

printf "offset\tvalue\tcrc16\n";
#Read N bytes from file and copy in the container
for my $counter (0 .. 5- 1)
{
    my $oneByte;
    read(FH, $oneByte, 1) or die "Error reading $inFile!";
    my $ctx2 = Digest::CRC->new( type => 'crc16' );
    my $digest2 = ($ctx2->add($oneByte))->hexdigest;
    # PRINT for debugging
    printf "0x%04X\t0x%02X\t0x", $counter, ord $oneByte;
    print $digest2, "\n";
}

Considering this binary input

enter image description here

I obtain the result:

enter image description here

The script is performing byte-by-byte CRC16 (correct by the way), but I need the CRC16 of the full binary stream of 5 bytes (the expected value should be 0x6CD6). Where am I wrong in the script?


Solution

  • Calling hexdigest or digest or b64digest clears the buffer and begins the next digest from scratch. (If you were computing digests of several files/streams, you wouldn't want the data from one stream to affect the digest of a separate stream).

    So wait until the stream is completely read to call digest

    ... {
        ...
        $ctx2->add($oneByte);
    }
    print "digest = ", $ctx2->hexdigest, "\n";
    

    Or to help in debugging, save the stream and redigest the stream after each new byte

    my $manyBytes = "";
    ... {
        ...
        $manyBytes .= $oneByte;
        $digest2 = $ctx2->add($manyBytes)->hexdigest;
        ...
    }