modulo 256 checksum

7,560 views
Skip to first unread message

Kevin O

unread,
Apr 13, 2012, 4:54:37 PM4/13/12
to nod...@googlegroups.com
I am working on a node integration to a home automation device. The device has an ASCII protocol that I am building a parser and a command generator for. 

All of the ASCII messages that I send need to be appended with modulo 256 checksum. Here is the exact verbiage from the documentation.

2-digit checksum: This is the hexadecimal two’s complement of the modulo-256 sum of the ASCII values of all characters in the message excluding the checksum itself and the CR-LF terminator at the end of the message. Permissible characters are ASCII 0-9 and upper case A-F. When all the characters are added to the Checksum, the value should equal 0.

I have an ASCII string of 09sw13100 that is supposed to result in hex B8. That is what I am using as my test.

Any ideas on how to implement this? I've tried the function below but it produces the wrong output.

function calcChecksum(asciiString) {
  var buf = new Buffer(asciiString);
  var sum = 0;
  for(var i=0; i<buf.length; i++) {
    sum = sum + buf[i];
  }
  sum = sum%256;
  return sum.toString(16);

Tim Caswell

unread,
Apr 13, 2012, 5:03:58 PM4/13/12
to nod...@googlegroups.com
Looks like you're missing the two's compliment part and the upper case part.

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Tim Caswell

unread,
Apr 13, 2012, 5:12:44 PM4/13/12
to nod...@googlegroups.com
Try this:

function calcChecksum(string) {
  var buf = new Buffer(string);

  // Calculate the modulo 256 checksum
  var sum = 0;
  for (var i = 0, l = buf.length; i < l; i++) {
    sum = (sum + buf[i]) % 256;
  }
  // Find the compliment
  sum = 256 - sum;

  // Convert to a two byte uppercase hex value
  var chars = sum.toString(16).toUpperCase();
  if (chars.length ==1 ) chars = "0" + chars;
  return chars;

Jann Horn

unread,
Apr 13, 2012, 5:13:37 PM4/13/12
to nod...@googlegroups.com
On Fri, Apr 13, 2012 at 01:54:37PM -0700, Kevin O wrote:
> 2-digit checksum: This is the hexadecimal two’s complement of the
> > modulo-256 sum of

Well, you forgot to make it two's complement.



> Any ideas on how to implement this? I've tried the function below but it
> produces the wrong output.
>
> function calcChecksum(asciiString) {
> var buf = new Buffer(asciiString);
> var sum = 0;
> for(var i=0; i<buf.length; i++) {
> sum = sum + buf[i];
> }
> sum = sum%256;

Here, insert `sum = sum ^ 0xff`. That should work, I think.

> return sum.toString(16);
> }

Kevin O

unread,
Apr 13, 2012, 5:19:43 PM4/13/12
to nod...@googlegroups.com
Incredible! Thanks, Tim.

mscdex

unread,
Apr 13, 2012, 5:22:13 PM4/13/12
to nodejs
On Apr 13, 4:54 pm, Kevin O <kevinohar...@gmail.com> wrote:
> I have an ASCII string of *09sw13100* that is supposed to result in hex *B8.
> *That is what I am using as my test.
>
> Any ideas on how to implement this? I've tried the function below but it
> produces the wrong output.
>
> [...]

Try this:
function calcChecksum(str) {
var sum = 0, i = 0, len = str.length;
for (; i<len; ++i) {
sum += str.charCodeAt(i);
if (sum & 0x80)
sum = (0xff - sum + 1) * -1;
}
sum = sum % 256;
if (sum < 0)
sum *= -1;
return sum.toString(16);
}

console.log(calcChecksum('09sw13100'));
// output: b8

Paddy Byers

unread,
Apr 13, 2012, 5:23:38 PM4/13/12
to nod...@googlegroups.com
Or more simply:

  var buf = new Buffer(asciiString);
  var sum = 0;
  for(var i=0; i<buf.length; i++) {
    sum -= buf[i];
  }
  sum = sum&0xff;
  return sum.toString(16).toUpperCase();

Paddy

Jorge

unread,
Apr 13, 2012, 5:34:45 PM4/13/12
to nod...@googlegroups.com

function calcChecksum(asciiString) {
var sum= 0, i= asciiString.length;
while (i--) sum+= asciiString.charCodeAt(i);
sum= (256- (sum%= 256));
return (sum<16 ? '0' : '')+ sum.toString(16).toUpperCase();
}

calcChecksum('09sw13100')
-> "B8"
--
Jorge.

Kevin Swiber

unread,
Apr 13, 2012, 5:38:50 PM4/13/12
to nod...@googlegroups.com
On Fri, Apr 13, 2012 at 4:54 PM, Kevin O <kevino...@gmail.com> wrote:
I am working on a node integration to a home automation device. The device has an ASCII protocol that I am building a parser and a command generator for. 

This sounds pretty sweet, and it would be cool to see this as a module on npm.  Any plans to release it when it's ready?

--  
Kevin Swiber
Projects: https://github.com/kevinswiber
Twitter: @kevinswiber

Jorge

unread,
Apr 13, 2012, 5:46:52 PM4/13/12
to nod...@googlegroups.com

Yeah, cool, that's the best !

function calcChecksum(asciiString) {
var sum= 0;
var i= asciiString.length;
while (i--) sum-= asciiString.charCodeAt(i);
return ((sum&= 0xff) < 16 ? '0' : '')+ sum.toString(16).toUpperCase();

Kevin O

unread,
Apr 13, 2012, 5:51:36 PM4/13/12
to nod...@googlegroups.com
Actually yes. I have this "other" project that is taking priority though. ;)
Reply all
Reply to author
Forward
0 new messages