Checksum code

jepler at unpythonic.net jepler at unpythonic.net
Mon May 27 15:16:48 EDT 2002


I think that you can simply write
    def _add32(x, y):
	return (x+y) & 0xFFFFFFFFl

    def calcChecksum(s):
	if len(s) & 3:
	    s = (s+"\0\0\0")
	    s = s[:len(s)&3]
	sum = 0
	for n in unpack(">%dL" % (len(s)/4), s):
	    sum = (sum + n) & 0xFFFFFFFFl
	return sum
under Python 2.2.  calcChecksum should even work under 1.5.2. (the items in
the list from unpack() will all be longs)

The difference is that this doesn't work under "overflow-prone" Python, 
and I've treated all math as unsigned by using "L" instead of "l" to
decode.  I'm not exactly sure what that does to your 'checksum =
_add32(..., -checkSum)' step, mathematically speaking... it appears to
leave the value "unchanged":
    >>> x
    4294967295L
    >>> y
    -1
    >>> _add32(0xb1b0afba, x)
    2981146553L
    >>> _add32(0xb1b0afba, y)
    -1313820743
    >>> hex(_add32(0xb1b0afba, y))
    '0xb1b0afb9'
    >>> hex(_add32(0xb1b0afba, x))
    '0xB1B0AFB9L'
... except for the matter of where the sign bit lives.

It looks like the following version would "work" in 1.5.2 and 2.2:
    def _add32(x, y):
	return (0L+x+y) & 0xFFFFFFFFl
the math again becomes math on longs, and the & restricts to 32 bits
(intermediate results are calculated with more bits and cut down to
size here)

Jeff





More information about the Python-list mailing list