[Checksum] XOR

Rekent een XOR checksum uit in c++ (bijv voor Arduino). Je kunt het gebruiken om ofwel een zin te decoderen of hem aan je zin toe te voegen. Deze zelfde checksum is gebruikt in GPS NMEA strings. Je kunt dus kijken of de ontvangen zin uit een GPS apparaat klopt (dus dat er niets fout is gegaan in de transmissie). Deze code heb ik ook voor C#, zodat je C# met C++ kan interfacen zonder dat er verkeerde data door komt.

De zin lijkt gewoonlijk op:

$$blablablablabliebloe*

Dan reken je de checksum uit van het bovenstaande en plak je het achter de zin:

$$blablablabalbablab*6C

Waarin 6C dus de checksum is. Op deze manier kun je informatie controleren of het is aangekomen, als je weet welk checksumalgoritme is gebruikt. De CRC16 checksum is veel beter, maar deze is lekker makkelijk en voldoet prima.

  1. // Validates the checksum on an (for instance NMEA) string
  2. // Returns 1 on valid checksum, 0 otherwise
  3. int validateChecksum(void) {
  4.   char gotSum[2];
  5.   gotSum[0] = buffer[strlen(buffer) - 2];
  6.   gotSum[1] = buffer[strlen(buffer) - 1];
  7.   // Check that the checksums match up
  8.   if ((16 * atoh(gotSum[0])) + atoh(gotSum[1]) == getCheckSum(buffer)) return 1;
  9.   else return 0;
  10. }
  11.  
  12. // Calculates the checksum for a given string
  13. // returns as integer
  14. int getCheckSum(char *string) {
  15.   int i;
  16.   int XOR;
  17.   int c;
  18.   // Calculate checksum ignoring any $'s in the string
  19.   for (XOR = 0, i = 0; i < strlen(string); i++) {
  20.     c = (unsigned char)string[i];
  21.     if (c == '*') break;
  22.     if (c != '$') XOR ^= c;
  23.   }
  24.   return XOR;
  25. }

Calculate a XOR checksum in c++ (for Arduino)
You can use this to either decode a string you made on your own, but this is genarlly also used for NMEA strings, that are used for GPS. So you can decode a checksum for a GPS sentence and check it. Also, see the code in C# for this if you want to interface like i have used this for.

The sentence generally looks like this:

$$blablablablabliebloe*

Then you calculate the checksum from the above to produce something like

$$blablablabalbablab*6C

in which that 6C is then the checkum. This way you make sure your info is correct. better is even to use a CRC16 checksum, but this code is fairly easy and robust. You can never look past code you don’t understand.

  1. // Validates the checksum on an (for instance NMEA) string
  2. // Returns 1 on valid checksum, 0 otherwise
  3. int validateChecksum(void) {
  4.   char gotSum[2];
  5.   gotSum[0] = buffer[strlen(buffer) - 2];
  6.   gotSum[1] = buffer[strlen(buffer) - 1];
  7.   // Check that the checksums match up
  8.   if ((16 * atoh(gotSum[0])) + atoh(gotSum[1]) == getCheckSum(buffer)) return 1;
  9.   else return 0;
  10. }
  11.  
  12. // Calculates the checksum for a given string
  13. // returns as integer
  14. int getCheckSum(char *string) {
  15.   int i;
  16.   int XOR;
  17.   int c;
  18.   // Calculate checksum ignoring any $'s in the string
  19.   for (XOR = 0, i = 0; i < strlen(string); i++) {
  20.     c = (unsigned char)string[i];
  21.     if (c == '*') break;
  22.     if (c != '$') XOR ^= c;
  23.   }
  24.   return XOR;
  25. }

Tim Zaman

MSc Biorobotics. Specialization in computer vision and deep learning. Works at NVIDIA.

You may also like...