3

I am being asked to do a checksum on this text with the bit size being 16: "AAAAAAAAAA\nX"

At first the description seemed like it wanted the Fletcher-16 checksum. But the output of Fletcher's checksum performed on the above text yielded 8aee in hex. The example file says that the modular sum algorithm (minus the two's complement) should output 509d in hex.

The only other info is the standard "every two characters should be added to the checksum."

Besides using the generic Fletcher-16 checksum provided on the corresponding Wikipedia page, I have tried using this solution found here: calculating-a-16-bit-checksum to no avail. This code produced the hex value of 4f27.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
Mook
  • 39
  • 7

1 Answers1

2

Simply adding the data seeing it as an array of big-endian 16-bit integers produced the result 509d.

#include <stdio.h>

int main(void) {
    char data[] = "AAAAAAAAAA\nX";
    int sum = 0;
    int i;
    for(i = 0; data[i] != '\0' && data[i + 1] != '\0'; i += 2) {
        int value = ((unsigned char)data[i] << 8) | (unsigned char)data[i + 1];
        sum = (sum + value) & 0xffff;
    }
    printf("%04x\n", sum);
    return 0;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Okay I can see where I was misunderstanding was now. Thank you for your fast reply. – Mook Apr 18 '21 at 00:54
  • For the pedantic: use `unsigned char*` for data access, else `data[i] != '\0'` (2 zeros) and `(unsigned char)data[i]` is incorrect for the dinosaur non-2's complement machines. `(unsigned char)data[i] << 8` risks overflow with 16-bit `int`. Better to use `unsigned sum` with `"%04x"` anyways to avoid 8 digit output when `sum < 0` on 32-bit machines. – chux - Reinstate Monica Apr 18 '21 at 02:12
  • @chux-ReinstateMonica Why is `data[i] != '\0'` incorrect? – MikeCAT Apr 18 '21 at 02:14
  • Rare non-2's complement machines have +0 and -0 or +0 and trap. In C, a string's final _null character_ is only the +0 one. See "For all functions in this subclause, each character shall be interpreted as if it had the type unsigned char (and therefore every possible object representation is valid and has a different value)." 7.24.1 3 Accessing `data[i] != '\0'` can trigger on both +0 and -0. – chux - Reinstate Monica Apr 18 '21 at 02:57
  • @MikeCAT I was attempting to add for a 32-bit checksum doing it this same way and can’t seem to grasp the concept. I tried incrementing by 4 and tried various oring combinations. Would I still bit shift left 8 or would it be 16? – Mook Apr 18 '21 at 12:04
  • @Mook The shift will be 24, 16, and 8 (and 0), according to the position of each byte. – MikeCAT Apr 18 '21 at 12:51
  • @MikeCAT and then I would or each of those bit shifts with the corresponding position in the array and add to checksum, right? – Mook Apr 18 '21 at 13:22
  • @Mook Exactly, go ahead to implement that and test. – MikeCAT Apr 18 '21 at 13:24
  • @MikeCAT Alright I've edited it some to look like this: `for(i = 0; data[i] != '\0' && data[i + 1] != '\0' && data[i + 2] != '\0' && data[i + 3] != '\0'; i += 4) { int value = ((unsigned char)data[i] << 8) | (unsigned char)data[i + 1]; int valueTwo = ((unsigned char)data[i] << 16) | (unsigned char)data[i + 2]; int valueThree = ((unsigned char)data[i] << 24) | (unsigned char)data[i + 3]; sum = (sum + value + valueTwo + valueThree) & 0xffffffff; } ` and get an output of **c3c3c529**. I am not sure if that would be correct or not. – Mook Apr 18 '21 at 13:50