OT: one's compliment 8 bit checksum
Oleg Goldshmidt
pub at goldshmidt.org
Mon Oct 24 18:12:24 IST 2011
On Mon, Oct 24, 2011 at 4:20 PM, geoffrey mendelson
<geoffreymendelson at gmail.com> wrote:
> I need to calculate a one's compliment 8 bit (not 16 bit, not 2's
> compliment) checksum.
>
> What would be really nice is a C subroutine I can call passing the number of
> bytes and a pointer to the data.
>
> Any license I can use will be ok, I don't plan on distributing it, but if I
> do, source code will be included.
>
> It's for use in a program that changes one field in a control file that is
> loaded into the ROM of a 1980's vintage embedded system.
This shouldn't be too difficult in general but this last sentence
makes me ask a couple of important questions:
1. Is the platform 8 bit or 16 bit or 32 bit? I am asking because as
far as I understand the algorithm it involves the carry bit.
2. It is not clear to me if endianness is relevant (it is for TCP
checksums but those are 16 bit). At least give it an extra 15 seconds
of thought if the platform is weird-endian.
Assuming 16+ bit platform here is what - I think - the code may look
like. Others, more experienced than me, may find it incorrect but then
they will post corrections. I only compiled it, I never ran it before
"shipping". You may consider it under MIT license, but I don't regard
it original work, for obvious reasons. I do not know if the platform
(the cross-compiler?) has stdint.h, but one way or another you need an
8-bit unsigned integer type.
#include <stdint.h>
uint8_t cksum(const uint8_t* msg, int noct) {
uint8_t sum = 0;
while (noct-- > 0) {
sum += *(msg++);
}
/* if carry bits are produced add them (sum >> 8) back
* to the LSBs */
sum = (sum >> 8) + (sum & 0xFF);
/* we may still have a carry bit, so do it the second time;
* it can only overflow once: FF+FF=1FE -> FE+1=FF */
sum += (sum >> 8);
/* return inverted bits */
return ~sum;
}
--
Oleg Goldshmidt | pub at goldshmidt.org
More information about the Linux-il
mailing list