Tuesday August 22, 2017

Java XOR Checksum Calculator

Date: 05/17/2009
Author:
Wayne Eggert

Introduction
Ever wanted to calculate XOR checksums in Java? A while back my exercise bike broke -- it wasn't reading the speed any more and I thought there might be a simple fix. Turns out, something in the circuit board went bad. Not having any schematics for the thing has made it difficult to diagnose. So I got the idea of possibly replacing the "computer" with something that could interface with the NetAthlon bike training software. This meant finding information on an open-source exercise bike protocol where I could learn how to communicate with the software. Luckily one such protocol is called CSAFE (Communications Specification for Fitness Equipment) and there is a wealth of information available on it at the FitLinxx Site. When sending messages to and from a bike that supports the CSAFE protocol, the XOR checksum of the data being sent is calculated & included as the last byte so the receiver can verify the data was received correctly. It was quite tedious to do all the XORs by hand, so I wrote a Java program to take a string of hex byte and calculate the XOR.

Example of Hex String
Here's an example of the hex string that would represent data being sent to the host using the CSAFE protocol. The hex bits represent different commands, which you need not worry about in this tutorial, but might contain commands like "speed = 5mph, calories = 300, heart rate = 90".

87 A5 03 00 40 00 A7 03 30 00 00 B0 01 10 B4 03 00 01 00 A4 02 00 01


The Hard Way - Manually XOR
The manual way of computing an XOR cksum would be to take each hex byte, convert it to binary & get the result of the XOR with the previous hex byte.

So taking the hex string above, we'd start with hex "87". Since there is no bit before it, according to the CSAFE protocol we would XOR with hex "00", which basically just gives you hex "87" as the result again.

hex 00 = binary 00000000
hex 87 = binary 10000111


An XOR takes each binary bit value in the 1st binary string and compares it to the corresponding binary bit value in the 2nd binary string. If the values match (1 and 1, or 0 and 0) then the XOR of the bits would be a 0. If the values don't match (ie. 1 and 0, or 0 and 1) then the XOR of the bits would be 1.

So in the values above, XOR of the two binary strings would be as follows:

(hex 00 bit) ^ (corresponding hex 87 bit)

0 ^ 1 = 1
0 ^ 0 = 0
0 ^ 0 = 0
0 ^ 0 = 0
0 ^ 0 = 0
0 ^ 1 = 1
0 ^ 1 = 1
0 ^ 1 = 1

So the final XOR of the hex byte 00 and hex byte 87 would be binary 10000111 (which is also hex 87).


Next, we'd move onto comparing the previous result (ie. binary 10000111) with the next hex byte "A5"

hex 87 = binary 10000111 hex A5 = binary 10100101

(hex 87 bit) ^ (corresponding hex A5 bit)

1 ^ 1 = 0
0 ^ 0 = 0
0 ^ 1 = 1
0 ^ 0 = 0
0 ^ 0 = 0
1 ^ 1 = 0
1 ^ 0 = 1
1 ^ 1 = 0

So the final XOR of hex byte 87 and hex byte A5 would be binary 00100010 (which is also hex 22).

Next, we'd move onto comparing the previous result (ie. binary 00100010) with the next hex byte "03"

hex 22 = binary 00100010 hex 03 = binary 00000011

(hex 22 bit) ^ (corresponding hex 03 bit)

0 ^ 0 = 0
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 0 = 0
0 ^ 0 = 0
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1

So the final XOR of hex byte 22 and hex byte 03 would be binary 00100001 (which is also hex 21).

We'd continue calculating the summation of hex XORs in this manner until all of the hex bytes in the original hex string were processed. The end result would be the checksum and in the case of the CSAFE protocol, the resultant hex byte would be included as the last byte of the data sent in transmissions from the exercise bike to the host program. In the CSAFE protocol, the cksum value is important since the host program either sees a valid cksum and processes the data, or sees an invalid cksum and tosses out the request.

page1 page2


Comments:
Best on the web
Posted 04/18/13 8:33AM by Anonymous Techdoser
Super!
Love the code and explanation.
Re: Hi Im getting 66 as result for the same input as above?
Posted 03/12/13 7:21AM by AceBHound
Thanks to both of you pointing this out, I must have missed copying the "23" hex value with the hex string. The correct hex value should be 0x66 (ie. 66) with the hex 0x23 included in the input string.
Re: Hi Im getting 66 as result for the same input as above?
Posted 03/12/13 2:15AM by Anonymous Techdoser
i was getting 66 too
but when selecting input as only
"87 A5 03 00 40 00 A7 03 30 00 00 B0 01 10 B4 03 00 01 00 A4 02 00 01" excluding 23 (which is the length of the hex tokens) the result is 45.
CSafe Code Sample
Posted 09/27/12 12:50PM by fabiana
Does anybody has a basic CSafe Code in Java or C/C++/C# ? Thanks!!!
Im getting 66 as result
Posted 12/14/11 4:18AM by gk_sezhian
Hi Im getting 66 as result for the same input as above?
Re: Implémentation of CSafe protocol
Posted 09/24/11 11:49AM by AceBHound
Sorry, I don't have any more information on implementing the CSAFE protocol at this time. The fitlinxx.com/CSAFE describes the protocol and should help from a coding perspective, but it doesn't have any code examples. You would need to implement the hardware
Implémentation of CSafe protocol
Posted 09/19/11 10:10AM by delleyma
Hello,
thanks for your code!

I'm actually working in a project where I have to implement CSafe protocol .
I can't find how to do it.
Could help me on this ?

Thanks a lot !
Thanks a lot!
Posted 03/14/10 2:12PM by sdime
Many thanks to author! This code helped me to calculate xor checksum for my GPS tracker device!