sorbet - 1 year ago 127
Python Question

# Subtracting 8-bit integers in Python

I'm trying to use Python to calculate a checksum by repeatedly subtracting a series of 8 bit values. However, I don't know how to do this in Python.

In context:
I have the following C code I'm trying to convert to Python:

``````#define uint8_t unsigned char
static uint8_t fix_header(uint8_t *header) {
uint8_t sum = 0;
uint8_t count = 0xbc - 0xa0;

/* complement check of 0xa0 - 0xbc */
header = header + 0xa0;

while (count-- > 0) {
sum = sum - *header++;
}

sum = (sum - 0x19);

return sum;
``````

It's the checksum code for GBA game headers. I'm having trouble replicating this in Python. I can do everything except
`sum = sum - *header++;`
, since (as far as I know), Python has no limit on how large a variable can be. I've tried this using Python's
`int`
but this gives incorrect checksums. From what I can see the 8-bit limit is doing something special I don't understand or know about.

Your help is appreciated!

Answer Source

To do 8-bit arithmetic in Python, simply do regular integer arithmetic and strip off the last 8 bits of the result.

``````count = (0xbc - 0xa0) & 0xff
``````

This works for unsigned values. If you need a signed result, check to see if it's greater than 127 and subtract 256 if it is.

``````count = count - 256 if count > 127 else count
``````

This whole function is rather un-Pythonic though. I'd translate it as follows:

``````def fix_header(header):
sum = 0
for b in header[0xa0:0xbc]:
sum -= ord(b)
sum = (sum - 0x19) & 0xff
return sum
``````

I make the assumption here that `header` is a bytestring and thus `ord` is necessary to turn the bytes into integers. I also think that converting the result to 8 bit can be done once at the end instead of at every calculation.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download