unsigned char CheckSum(unsigned char *uBuff, unsigned char uBuffLen){
unsigned char i, uSum=0;
for(i=0; i < uBuffLen; i++){
uSum = uSum + uBuff[i];
}
uSum = (~uSum) + 1;
return uSum;
}
unsigned char CheckSum(unsigned char *uBuff, unsigned char uBuffLen){
unsigned char i, uSum=0;
for(i=0; i < uBuffLen; i++){
uSum = uSum + uBuff[i];
}
uSum = (~uSum) + 1;
return uSum;
}
The algorithm is straightforward in Python, with no change - however, the final value composition, which has to be binary, has to be taken care of. To begin, of course the buffer has to be an object of the type "bytes" or some other one that a byte at a time intervenes (bytearray, memoryview, array.array, etc ...). As in Python these objects already have the known length, the second parameter is not necessary.
The "for" could be done with 3 lines:
result = 0
for element in buffer:
result += element
But - there you note that if it is just to sum all the elements of an iterable, the native function sum
of Python already does this - that is, the t = 3 linash above are equivalent to:
result = sum (buffer)
From here comes the part where you have to know what is happening with the numbers - regardless of language. In its C function, the accumulator "uSum" is an unsigned Char, which means that it is a variable that only contains numbers from 0 to 255 (8 bits) - and when the sum exceeds this, the upper bits are simply discarded in machine architecture (in the CPU). The integers in Python, by default, have indeterminate length - so the sum
function returns the total sum of bytes in a buffer. To discard the bits in positions greater than 8, and only have the value between 0 and 255, we have two options: place that number in a data structure that only accepts 8-bit numbers, discarding the rest - as in C, or , it uses the bit and bit-by-bit operator ( &
in both Python and C), with a number that has only the 8 bits that are of interest in 1 - (this ensures that all others go to 0) . Or even the module operator ( %
) - remainder of division - since we only want the lowest bits.
result = sum(buffer) & 0b11111111
The 2 add-on operator that worried you so much, is exactly the same in Python - the ~
unary. Only, as before, the number operated - that is, so far the whole function could be written as:
def checksum(buffer):
result = ~(sum(buffer) & 0b11111111) + 1
return result
Now - there is one last thing - which is precisely because the complement of 2 is done in a 1-byte variable with no signal in C: the result is always positive in C. In Python, again, with its numbers without limitation, result is negative. So to get that positive number back, the best way might be to drop that number into a bytes object created by the struct
module of Python - and then read that byte. This is because the struct.pack
method allows you to define exactly how to interpret the given number as bytes in memory - and then say that we want to import our number less than 8 bits with a signal - (using the code "b" as in the documentation ) - and read this byte later:
import struct
def checksum(buffer):
result = sum(buffer) & 0b11111111
result = ~result + 1
result = struct.pack("b", result)[0]
return result