Re: Help bits & bytes

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



byte toAsc(int b)
{
return (byte)(b + ((b <= 9)?'0':'A'-10));
}


This bit of code translates an integer value, supposedly between 0 and
15, to its corresponding hexadecimal value. It's equivalent to the
following:

byte toAsc(int b)
{
if (b <= 9)
{
return b + '0';
}
else
{
return b - 10 + 'A';
}
}

The first "return" statement takes a value between 0 and 9 and adds it
to the character '0'. Since the characters '0' to '9' are conveniently
together and in sequence, this will result in a value of 1 yielding
'1', a value of 2 yielding '2', etc.

The second "return" statement handles values 10 to 15. It subtracts 10
from the value (making it a value 0 to 5. It then adds this to 'A',
meaning that 0 gives 'A', 1 gives 'B', 2 gives 'C', etc.

boolean checksum(byte[] line, int n, byte[]csb) {
byte cs=0;
for(int i=1;i < n;i++)
cs += line[i];
csb[0] = toAsc((cs & 0xf0) >> 4);
csb[1] = toAsc(cs & 0xf);
return csb[0] == line[n] && csb[1] == line[n+1];
}

This bit of code takes a line of characters and an index into the line.
It calculates the checksum on the line up to the index, and then
expects to find the checksum bytes at the two characters following the
index originally passed to the method.

(This a crap function contract by the way. It would have been much
clearer to pass in the length of the line, including the checksum, and
then do the work knowing that the checksum occupies the last two
characters of the line. Anyway, onward and upward....)

byte cs=0;
for(int i=1;i < n;i++)
cs += line[i];

This calculates to total value of all of the bytes in the line,
throwing away any bits that roll off the top. We're only interested in
the last byte of the total, anyway, so any loss of information doesn't
matter for checksum purposes.

csb[0] = toAsc((cs & 0xf0) >> 4);

the first byte of the checksum, csb[0], is the first 4 bits of the
8-bit byte in cs (the total of the bytes in the line), translated into
an ASCII character (as outlined above). The "& 0xf0" is really
redundant, because shifting right by 4 (>> 4) will toss away the lower
4 bits anyway. Nonetheless, the "& 0xf0" masks out the lower 4 bits.
So, if cs contains a value (in binary) something like 11011001, then
the "0xf0" will mask out the lower 4 bits, leaving "11010000". The
shift right by 4 (>> 4) will then shift this over, leaving "00001101",
which is "D" in hexadecimal. The toAsc method will then return the
character 'D'.

csb[1] = toAsc(cs & 0xf);

the second byte of the checksum, csb[1], is the lower four bits of the
total (cs & 0xf). the 0xf is really sloppy coding, as to make it
crystal clear the programmer should have written &0x0f. There's no
difference in functionality, but at least it highlights the fact that
you're masking out the high 4 bits. So, in our preceding example where
cs is 11011001, the result will be 00001001, which is 9, so toAsc will
return the character '9'.

Our checksum is now 'D9'.

return csb[0] == line[n] && csb[1] == line[n+1];

The checksum routine now checks to make sure that the last two
characters in the line are 'D' and '9'. It returns true if they are,
and false if they are not.

.



Relevant Pages

  • Re: Hex 0D 0A and serial question
    ... many secrets in sending data to a serial port using MSComm1. ... Your code is adding these characters to Out1 and Out2. ... You don't show how the checksum is ...
    (microsoft.public.vb.general.discussion)
  • Re: Python for Reverse Engineering
    ... There are 31 characters in the encoding. ... 124 bits are needed to encode the full space because ... this scheme then there's no extra space for a checksum. ... can change based on the index in the string. ...
    (comp.lang.python)
  • ASTM checksum
    ... Could I have some help calculating a checksum for data transmission to a ... The checksum is computed by adding the binary values of the characters, keeping the least significant eight bits of the result. ...
    (comp.lang.perl.misc)