Robin Becker wrote: > > > ULONG CalcTableChecksum(ULONG *Table, ULONG Length) > > { > > ULONG Sum = 0L; > > ULONG *Endptr = Table+((Length+3) & ~3) / sizeof(ULONG); > > > > while (Table < EndPtr) > > Sum += *Table++; > > return Sum; > > }
Is this what you want? import numpy def CalcTableChecksum(Table, Length=None): tmp = numpy.array(Table,dtype=numpy.uint32) if Length == None: Length = tmp.size endptr = ((Length+3) & ~3) / 4 return (tmp[0:endptr]).sum() as nx type(nx.array([1,2,3],dtype=nx.uint32)[0]) > so effectively we're doing only additions and letting bits roll off the end. > > Of course the actual semantics is dependent on what C unsigned arithmetic does > so we're relying on that being the same everywhere. > > This algorithm was pretty simple in Python until 2.3 when shifts over the end > of > ints started going wrong. For some reason we didn't do the obvious and just do > everything in longs and just mask off the upper bits. For some reason > (probably > my fault) we seem to have accumulated code like > > def _L2U32(L): > '''convert a long to u32''' > return unpack('l',pack('L',L))[0] > > > if sys.hexversion>=0x02030000: > def add32(x, y): > "Calculate (x + y) modulo 2**32" > return _L2U32((long(x)+y) & 0xffffffffL) > else: > def add32(x, y): > "Calculate (x + y) modulo 2**32" > lo = (x & 0xFFFF) + (y & 0xFFFF) > hi = (x >> 16) + (y >> 16) + (lo >> 16) > return (hi << 16) | (lo & 0xFFFF) > > def calcChecksum(data): > """Calculates TTF-style checksums""" > if len(data)&3: data = data + (4-(len(data)&3))*"\0" > sum = 0 > for n in unpack(">%dl" % (len(data)>>2), data): > sum = add32(sum,n) > return sum > > and also silly stuff like > > def testAdd32(self): > "Test add32" > self.assertEquals(add32(10, -6), 4) > self.assertEquals(add32(6, -10), -4) > self.assertEquals(add32(_L2U32(0x80000000L), -1), 0x7FFFFFFF) > self.assertEquals(add32(0x7FFFFFFF, 1), _L2U32(0x80000000L)) > > def testChecksum(self): > "Test calcChecksum function" > self.assertEquals(calcChecksum(""), 0) > self.assertEquals(calcChecksum("\1"), 0x01000000) > self.assertEquals(calcChecksum("\x01\x02\x03\x04\x10\x20\x30\x40"), > 0x11223344) > self.assertEquals(calcChecksum("\x81"), _L2U32(0x81000000L)) > _L2U32(0x80000000L)) > > where while it might be reasonable to do testing it seems the tests aren't > very > sensible eg what is -6 doing in a u32 test? This stuff just about works on a > 32 > bit machine, but is failing miserably on a 64bit AMD. As far as I can see I > just > need to use masked longs throughout. > > In a C extension I can still do the computation exfficiently on a 32bit > machine, > but I need to do masking for a 64 bit machine. > -- > Robin Becker -- http://mail.python.org/mailman/listinfo/python-list