I thought I'd challenge myself to see if I could figure this out. As I started looking into CRC algorithms, I quickly found myself in over my head. But I think that I was actually able to figure it out.

Looking at the source code of Digest::CRC, I took a guess that the value for 'const' should be 0 instead of '0xea82'. That got me closer for ASCII input. Combining that with the suggestion from the Anonymous Monk got me closer for hex input. In both cases what I mean by getting closer is that I got the right characters, but in the wrong order. Basically, I needed to reverse the output by bits. For example, with your sample header, I was getting 'c52' instead of '520c'. The two bits here are '0c' and '52'. Reversing the two bits of 'c52' (or '0c52') produces '520c'.

In searching for references for CRC-DNP checksums, I found an online checksum calculator (found here). I used it to 'verify' the output of the following code.

use strict; use warnings; use feature 'say'; use Digest::CRC; sub Left_Pad { my $value = shift; if (length($value) % 2) {$value = '0'.$value;} return $value; } sub Bitwise_Reverse { my $value = shift; $value = Left_Pad($value); my $offset = length($value); my $reversed; while ($offset > 0) { $offset -= 2; my $string = substr($value,$offset,2); $reversed .= $string; } return $reversed; } sub CRC_DNP_ASCII { my $value = shift; my $ctx = Digest::CRC->new(width=>16, init=>0x0, xorout=>0xffff, r +efin=>1, refout=>1, poly=>0x3d65, cont=>0); $ctx->add($value); my $digest = $ctx->hexdigest; my $crc = Bitwise_Reverse($digest); return $crc; } sub CRC_DNP_HEX { my $value = shift; my $ctx = Digest::CRC->new(width=>16, init=>0x0, xorout=>0xffff, r +efin=>1, refout=>1, poly=>0x3d65, cont=>0); my $offset = 0; while ($offset < length($value)) { my $string = substr($value,$offset,2); $ctx->add(chr(hex($string))); $offset += 2; } my $digest = $ctx->hexdigest; my $crc = Bitwise_Reverse($digest); return $crc; } my @data_list = ('056405F201000000','56405F201000000'); foreach my $data (@data_list) { say "Calculating CRC-DNP checksum for '$data':"; my $ascii = CRC_DNP_ASCII($data); say " ASCII input: $ascii"; my $hex = CRC_DNP_HEX($data); say " Hex input: $hex\n"; }

That produced the following output:

Calculating CRC-DNP checksum for '056405F201000000': ASCII input: 99fc Hex input: 520c Calculating CRC-DNP checksum for '56405F201000000': ASCII input: 0751 Hex input: 11e3

I've tried a few other examples to compare the output of my code versus the online calculator and I'm getting the same values for the CRC-DNP checksums.

Perhaps more knowledgeable monks might be able to identify issues with my code, but I think it should help you get further along with what you're trying to do.

UPDATE: Since the OP was cross posted, I cross posted this response (see here) as well to the same site.


In reply to Re: Using Digest::CRC to calculate DNP3 checksums by dasgar
in thread Using Digest::CRC to calculate DNP3 checksums by wdtj

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.